﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Markup;
using System.Windows.Media;
using System.Xml;
using System.Xml.Linq;
using DiagramDesigner.BusinessModelObject;
using Microsoft.Win32;
using DiagramDesigner.Controls;
using AvalonDock;
using Extensions = DiagramDesigner.Utils.Extensions;
using System.ComponentModel;
using DiagramDesigner.Utils;
using System.Windows.Media.Imaging;
using System.Xml.XPath;
using System.Xml.Serialization;
//using System.Drawing;
//using System.Drawing.Imaging;
using System.Windows.Interop;
using System.Text;
using System.Reflection;

namespace DiagramDesigner
{
    public partial class DesignerCanvas
    {
        #region Comandos
        public static RoutedCommand PointAtribute = new RoutedCommand();
        public static RoutedCommand LineAtribute = new RoutedCommand();
        public static RoutedCommand SurfaceAtribute = new RoutedCommand();
        public static RoutedCommand PointSetAtribute = new RoutedCommand();
        public static RoutedCommand LineSetAtribute = new RoutedCommand();
        public static RoutedCommand SurfaceSetAtribute = new RoutedCommand();
        public static RoutedCommand NonSpatialAtribute = new RoutedCommand();

        public static RoutedCommand TempPointAtribute = new RoutedCommand();
        public static RoutedCommand TempLineAtribute = new RoutedCommand();
        public static RoutedCommand TempSurfaceAtribute = new RoutedCommand();
        public static RoutedCommand TempPointSetAtribute = new RoutedCommand();
        public static RoutedCommand TempLineSetAtribute = new RoutedCommand();
        public static RoutedCommand TempSurfaceSetAtribute = new RoutedCommand();
        public static RoutedCommand TempNonSpatialAtribute = new RoutedCommand();


        public static RoutedCommand NoSpatialMeasure = new RoutedCommand();
        public static RoutedCommand PointMeasure = new RoutedCommand();
        public static RoutedCommand LineMeasure = new RoutedCommand();
        public static RoutedCommand SurfaceMeasure = new RoutedCommand();
        public static RoutedCommand PointSetMeasure = new RoutedCommand();
        public static RoutedCommand LineSetMeasure = new RoutedCommand();
        public static RoutedCommand SurfaceSetMeasure = new RoutedCommand();
        public static RoutedCommand NonSpatialMeasure = new RoutedCommand();

        public static RoutedCommand Group = new RoutedCommand();
        public static RoutedCommand Ungroup = new RoutedCommand();
        public static RoutedCommand BringForward = new RoutedCommand();
        public static RoutedCommand BringToFront = new RoutedCommand();
        public static RoutedCommand SendBackward = new RoutedCommand();
        public static RoutedCommand SendToBack = new RoutedCommand();
        public static RoutedCommand AlignTop = new RoutedCommand();
        public static RoutedCommand AlignVerticalCenters = new RoutedCommand();
        public static RoutedCommand AlignBottom = new RoutedCommand();
        public static RoutedCommand AlignLeft = new RoutedCommand();
        public static RoutedCommand AlignHorizontalCenters = new RoutedCommand();
        public static RoutedCommand AlignRight = new RoutedCommand();
        public static RoutedCommand DistributeHorizontal = new RoutedCommand();
        public static RoutedCommand DistributeVertical = new RoutedCommand();
        public static RoutedCommand SelectAll = new RoutedCommand();
        public static RoutedCommand Exit = new RoutedCommand();
        public static RoutedCommand ExportImage = new RoutedCommand();
        public static RoutedCommand OracleDdlScript = new RoutedCommand();
        #endregion

        #region Variables
        private string route = String.Empty;
        private Script typeScript;
        private string _XMLFileName;
        private XElement _XMLContent;
        #endregion

        #region Propiedades
        public string XMLFileName
        {
            get
            {
                return _XMLFileName;
            }
            set
            {
                _XMLFileName = value;
            }
        }
        public XElement XMLContent
        {
            get
            {
                return _XMLContent;
            }
            set
            {
                _XMLContent = value;
            }
        }
        #endregion

        public DesignerCanvas()
        {
            #region Propiedades
            _XMLFileName = String.Empty;
            _XMLContent = null;
            #endregion

            #region Comandos
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.New, New_Executed));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Open, Open_Executed));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Save, Save_Executed));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Print, Print_Executed));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Cut, Cut_Executed, Cut_Enabled));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Copy, Copy_Executed, Copy_Enabled));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Paste, Paste_Executed, Paste_Enabled));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Delete, Delete_Executed, Delete_Enabled));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.Close, Close_Executed));
            this.CommandBindings.Add(new CommandBinding(ApplicationCommands.SaveAs, SaveAs_Executed));

            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.Group, Group_Executed, Group_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.Ungroup, Ungroup_Executed, Ungroup_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.BringForward, BringForward_Executed, Order_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.BringToFront, BringToFront_Executed, Order_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SendBackward, SendBackward_Executed, Order_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SendToBack, SendToBack_Executed, Order_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.AlignTop, AlignTop_Executed, Align_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.AlignVerticalCenters, AlignVerticalCenters_Executed, Align_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.AlignBottom, AlignBottom_Executed, Align_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.AlignLeft, AlignLeft_Executed, Align_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.AlignHorizontalCenters, AlignHorizontalCenters_Executed, Align_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.AlignRight, AlignRight_Executed, Align_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.DistributeHorizontal, DistributeHorizontal_Executed, Distribute_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.DistributeVertical, DistributeVertical_Executed, Distribute_Enabled));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SelectAll, SelectAll_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.Exit, Exit_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.ExportImage, ExportImage_Executed));

            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.NoSpatialMeasure, NoSpatialMeasure_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.PointMeasure, PointMeasure_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.LineMeasure, LineMeasure_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SurfaceMeasure, SurfaceMeasure_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.PointSetMeasure, PointSetMeasure_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.LineSetMeasure, LineSetMeasure_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SurfaceSetMeasure, SurfaceSetMeasure_Executed));


            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.PointAtribute, Point_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.LineAtribute, Line_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SurfaceAtribute, Surface_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.PointSetAtribute, PointSet_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.LineSetAtribute, LineSet_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.SurfaceSetAtribute, SurfaceSet_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.NonSpatialAtribute, NonSpatialAtribute_Executed));

            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempPointAtribute, TempPoint_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempLineAtribute, TempLine_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempSurfaceAtribute, TempSurface_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempPointSetAtribute, TempPointSet_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempLineSetAtribute, TempLineSet_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempSurfaceSetAtribute, TempSurfaceSet_Executed));
            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.TempNonSpatialAtribute, TempNonSpatialAtribute_Executed));

            this.CommandBindings.Add(new CommandBinding(DesignerCanvas.OracleDdlScript, OracleDdlScript_Executed));
            #endregion

            SelectAll.InputGestures.Add(new KeyGesture(Key.A, ModifierKeys.Control));

            this.AllowDrop = true;
            Clipboard.Clear();
        }

        private void NoSpatialMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.None);
        }
        private void PointMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.Point);
        }
        private void LineMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.Line);
        }
        private void SurfaceMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.Surface);
        }
        private void PointSetMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.PointSet);
        }
        private void LineSetMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.LineSet);
        }
        private void SurfaceSetMeasure_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            MedidasEspacialNoEspacial(Utils.MeasureAttribute.TypeImageMeasureAttribute.SurfaceSet);
        }


        private void MedidasEspacialNoEspacial(MeasureAttribute.TypeImageMeasureAttribute tipo)
        {
            DesignerCanvas dcNew = new DesignerCanvas();
            ScrollViewer sv = (ScrollViewer)this.Parent;
            GroupBox gb = (GroupBox)sv.Parent;
            DocumentModel dm = (DocumentModel)gb.Parent;
            DocumentPane dp = (DocumentPane)dm.Parent;
            foreach (DocumentModel dmNew in dp.Items)
            {
                if (dmNew.IsActiveDocument)
                {
                    GroupBox gbNew = (GroupBox)dmNew.Content;
                    ScrollViewer svNew = (ScrollViewer)gbNew.Content;
                    dcNew = (DesignerCanvas)svNew.Content;
                }
            }

            List<ISelectable> obj = dcNew.SelectionService.CurrentSelection;
            DesignerItem ki = (DesignerItem)obj[0];
            BaseField at = null;

            switch (ki.Tipo)
            {
                case "FactRelationShipModel":
                    GUIFactTable ko = (GUIFactTable)((System.Windows.Controls.ContentControl)(ki)).Content;
                    AddMeasure nk = new AddMeasure();
                    nk.Title = "Add Measure";
                    nk.tbEtiqueta.Text = "Measure";
                    nk.stPrimary.Visibility = Visibility.Hidden;
                    nk.stNivel.Visibility = Visibility.Hidden;
                    nk.Height = 100;

                    nk.ShowDialog();
                    if (nk.Estado == "A")
                    {
                        bool oneColumn = true;
                        bool newColumn = true;
                        bool modifyItem = false;
                        List<Utils.MeasureAttribute> CurrentProducts = (List<Utils.MeasureAttribute>)ko.lstview.ItemsSource;// ko.lstview.DataContext as List<Utils.MeasureAttribute>;


                        foreach (Utils.MeasureAttribute dr in CurrentProducts)
                        {
                            if (dr.RutaImagen != "Resources/Images/blank.png")
                            {
                                oneColumn = false;
                            }
                        }
                        var m = new Utils.MeasureAttribute(nk.EsPrimaryKey, nk.txtMeasure.Text, nk.TipoTemporalSpatial,
                                                           tipo);

                        if (m.RutaImagen != "Resources/Images/blank.png")
                            newColumn = false;

                        if (oneColumn == true && newColumn == false)
                            modifyItem = true;
                        // seteando atributo para mostrar
                        ko.DesigItem = ki;
                        if (tipo == MeasureAttribute.TypeImageMeasureAttribute.None)
                        {
                            at = new MedidaNoEspacial
                                     {
                                         DataType = new TypeData { TipoDato = TypeDatos.Number },
                                         Name = nk.txtMeasure.Text
                                     };
                        }
                        else
                        {
                            at = new MedidaEspacial
                                     {
                                         Name = nk.txtMeasure.Text,
                                         AggregationFunction = TypeAggregationFunction.C
                                     };
                            m.FunctionAgregation = TypeAggregationFunction.C.ToString();
                        }
                        CurrentProducts.Add(m);
                        ((MainElementModel)ki.Item).Atributos.Add(ko.lstview.Items.Count - 1, at);

                        //ko.lstview.Items.Add(new Utils.MeasureAttribute(nk.EsPrimaryKey, nk.txtMeasure.Text, nk.TipoTemporalSpatial, Utils.MeasureAttribute.TypeImageMeasureAttribute.None));
                        ko.lstview.ItemsSource = CurrentProducts;
                        ko.lstview.Items.Refresh();
                        ko.lstview.SelectedIndex = ko.lstview.Items.Count - 1;

                        ko.OrganizarColumnas(modifyItem);
                    }
                    break;
                case "LevelModel":
                    GUILevel ko2 = (GUILevel)((System.Windows.Controls.ContentControl)(ki)).Content;
                    AddMeasure nk2 = new AddMeasure();
                    nk2.Title = "Add Attribute";
                    nk2.tbEtiqueta.Text = "Attribute";
                    nk2.ShowDialog();
                    if (nk2.Estado == "A")
                    {
                        List<Utils.MeasureAttribute> CurrentProducts = (List<Utils.MeasureAttribute>)ko2.lstview.ItemsSource;
                        CurrentProducts.Add(new Utils.MeasureAttribute(nk2.EsPrimaryKey, nk2.txtMeasure.Text, nk2.TipoTemporalSpatial, Utils.MeasureAttribute.TypeImageMeasureAttribute.None));

                        // seteando atributo para mostrar
                        ko2.DesigItem = ki;
                        if (tipo == MeasureAttribute.TypeImageMeasureAttribute.None)
                        {
                            at = new AtributoNoEspNoTemp
                                     {
                                         DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                                         Name = nk2.txtMeasure.Text,
                                         Key = (nk2.EsPrimaryKey == 1)
                                     ? TypeKey.Y
                                     : TypeKey.N
                                     };
                        }
                        else
                        {
                            at = new AtributoEspNoTemp
                            {
                                Name = nk2.txtMeasure.Text
                            };
                        }
                        //at = new AtributoEspNoTemp
                        //         {
                        //             DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                        //             Name = nk2.txtMeasure.Text
                        //         };
                        ((MainElementModel)ki.Item).Atributos.Add(ko2.lstview.Items.Count - 1, at);

                        //ko.lstview.Items.Add(new Utils.MeasureAttribute(nk.EsPrimaryKey, nk.txtMeasure.Text, nk.TipoTemporalSpatial, Utils.MeasureAttribute.TypeImageMeasureAttribute.None));
                        ko2.lstview.ItemsSource = CurrentProducts;
                        ko2.lstview.Items.Refresh();
                        ko2.lstview.SelectedIndex = ko2.lstview.Items.Count - 1;
                    }
                    break;
                case "LSLevelModel":
                    GUILSLevel ko3 = (GUILSLevel)((System.Windows.Controls.ContentControl)(ki)).Content;
                    AddMeasure nk3 = new AddMeasure();
                    nk3.Title = "Add Attribute";
                    nk3.tbEtiqueta.Text = "Attribute";
                    nk3.ShowDialog();
                    if (nk3.Estado == "A")
                    {
                        List<Utils.MeasureAttribute> CurrentProducts = (List<Utils.MeasureAttribute>)ko3.lstview.ItemsSource;
                        CurrentProducts.Add(new Utils.MeasureAttribute(nk3.EsPrimaryKey, nk3.txtMeasure.Text, nk3.TipoTemporalSpatial, Utils.MeasureAttribute.TypeImageMeasureAttribute.None));

                        // seteando atributo para mostrar
                        ko3.DesigItem = ki;
                        if (tipo == MeasureAttribute.TypeImageMeasureAttribute.None)
                        {
                            at = new AtributoNoEspNoTemp
                            {
                                DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                                Name = nk3.txtMeasure.Text,
                                Key = (nk3.EsPrimaryKey == 1)
                            ? TypeKey.Y
                            : TypeKey.N
                            };
                        }
                        else
                        {
                            at = new AtributoEspNoTemp
                            {
                                Name = nk3.txtMeasure.Text
                            };
                        }
                        ((MainElementModel)ki.Item).Atributos.Add(ko3.lstview.Items.Count - 1, at);

                        //ko.lstview.Items.Add(new Utils.MeasureAttribute(nk.EsPrimaryKey, nk.txtMeasure.Text, nk.TipoTemporalSpatial, Utils.MeasureAttribute.TypeImageMeasureAttribute.None));
                        ko3.lstview.ItemsSource = CurrentProducts;
                        ko3.lstview.Items.Refresh();
                        ko3.lstview.SelectedIndex = ko3.lstview.Items.Count - 1;
                    }
                    break;
                default:
                    break;
            }
        }

        private void AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute tipo, int esTemporal)
        {
            DesignerCanvas dcNew = new DesignerCanvas();
            ScrollViewer sv = (ScrollViewer)this.Parent;
            GroupBox gb = (GroupBox)sv.Parent;
            DocumentModel dm = (DocumentModel)gb.Parent;
            DocumentPane dp = (DocumentPane)dm.Parent;
            foreach (DocumentModel dmNew in dp.Items)
            {
                if (dmNew.IsActiveDocument)
                {
                    GroupBox gbNew = (GroupBox)dmNew.Content;
                    ScrollViewer svNew = (ScrollViewer)gbNew.Content;
                    dcNew = (DesignerCanvas)svNew.Content;
                }
            }

            List<ISelectable> obj = dcNew.SelectionService.CurrentSelection;
            DesignerItem ki;
            if (obj.Count > 1)
            {
                ki = (DesignerItem)obj[1];
            }
            else
            {
                ki = (DesignerItem)obj[0];
            }


            switch (ki.Tipo)
            {
                //Este caso no se a nivel de atributos
                case "FactRelationShipModel":
                    GUIFactTable ko = (GUIFactTable)ki.Content;
                    AddMeasure nk = new AddMeasure();
                    nk.Title = "Add Measure";
                    nk.tbEtiqueta.Text = "Measure";
                    nk.ShowDialog();
                    BaseField at = null;
                    if (nk.Estado == "A")
                    {
                        List<Utils.MeasureAttribute> CurrentProducts = (List<Utils.MeasureAttribute>)ko.lstview.ItemsSource;
                        var m = new Utils.MeasureAttribute(nk.EsPrimaryKey, nk.txtMeasure.Text, esTemporal,
                                                           tipo);


                        // seteando atributo para mostrar
                        ko.DesigItem = ki;
                        if (tipo == MeasureAttribute.TypeImageMeasureAttribute.None)
                        {
                            at = new MedidaNoEspacial
                            {
                                DataType = new TypeData { TipoDato = TypeDatos.Number },
                                Name = nk.txtMeasure.Text
                            };
                        }
                        else
                        {
                            at = new MedidaEspacial
                            {
                                Name = nk.txtMeasure.Text,
                                AggregationFunction = TypeAggregationFunction.C
                            };
                            m.FunctionAgregation = TypeAggregationFunction.C.ToString();
                        }
                        CurrentProducts.Add(m);
                        ((MainElementModel)ki.Item).Atributos.Add(ko.lstview.Items.Count - 1, at);

                        ko.lstview.ItemsSource = CurrentProducts;
                        ko.lstview.Items.Refresh();
                        ko.lstview.SelectedIndex = ko.lstview.Items.Count - 1;
                    }
                    break;
                case "LevelModel":
                    GUILevel ko2 = (GUILevel)ki.Content;

                    var imageSource = mt_DevolverImagen(tipo.ToString());
                    if (imageSource != string.Empty && tipo != MeasureAttribute.TypeImageMeasureAttribute.None)
                    {
                        Uri myUriTimeSurface = new Uri(imageSource, UriKind.RelativeOrAbsolute);
                        BitmapImage imageTimeSurface = new BitmapImage();
                        imageTimeSurface.BeginInit();
                        imageTimeSurface.UriSource = myUriTimeSurface;
                        imageTimeSurface.EndInit();

                        ko2.imgSource.Height = 20;
                        ko2.imgSource.Source = imageTimeSurface;
                        ko2.OrganizarCabecera();

                        if (esTemporal == 0)
                            at = new AtributoEspNoTemp { Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), tipo.ToString().Replace("Time", "")) };
                        else
                            at = new AtributoEspTemp { Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), tipo.ToString().Replace("Time", "")) };

                        var d = ((MainElementModel)ki.Item).Atributos;
                        if (d.ContainsKey(-1))
                            d[-1] = at;
                        else
                            d.Add(-1, at);

                        var element = ((LevelModel)ko2.DesigItem.Item);
                        element.HasTemporalImage = imageSource.Contains("Time");
                        //element.Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), tipo.ToString().Replace("Time", ""));
                        //ShowProperties(ki);
                    }
                    else
                    {
                        AddMeasure nk2 = new AddMeasure();
                        nk2.Title = "Add Attribute";
                        nk2.tbEtiqueta.Text = "Attribute";
                        nk2.stNivel.Visibility = Visibility.Hidden;
                        nk2.ShowDialog();
                        if (nk2.Estado == "A")
                        {
                            //ko3.lstview.Items.Add(nk3.txtMeasure.Text);
                            List<Utils.MeasureAttribute> CurrentProducts = (List<Utils.MeasureAttribute>)ko2.lstview.ItemsSource;
                            CurrentProducts.Add(new Utils.MeasureAttribute(nk2.EsPrimaryKey, nk2.txtMeasure.Text, esTemporal, tipo));

                            // seteando atributo para mostrar
                            ko2.DesigItem = ki;
                            if (tipo == MeasureAttribute.TypeImageMeasureAttribute.None && esTemporal == 0)
                            {
                                at = new AtributoNoEspNoTemp
                                {
                                    DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                                    Name = nk2.txtMeasure.Text,
                                    Key = (nk2.EsPrimaryKey == 1)
                                ? TypeKey.Y
                                : TypeKey.N
                                };
                            }
                            else
                            {
                                at = new AtributoNoEspTemp
                                {
                                    DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                                    Name = nk2.txtMeasure.Text,
                                    Key = (nk2.EsPrimaryKey == 1)
                                             ? TypeKey.Y
                                             : TypeKey.N
                                };
                            }
                            ((MainElementModel)ki.Item).Atributos.Add(ko2.lstview.Items.Count - 1, at);

                            ko2.lstview.ItemsSource = CurrentProducts;
                            ko2.lstview.Items.Refresh();
                            ko2.lstview.SelectedIndex = ko2.lstview.Items.Count - 1;
                            ko2.OrganizarColumnas();

                        }
                    }
                    break;
                case "LSLevelModel":
                    GUILSLevel ko3 = (GUILSLevel)ki.Content;

                    var imageSource2 = mt_DevolverImagen(tipo.ToString());

                    if (imageSource2 != string.Empty && tipo != MeasureAttribute.TypeImageMeasureAttribute.None)
                    {
                        Uri myUriTimeSurface = new Uri(imageSource2, UriKind.RelativeOrAbsolute);
                        BitmapImage imageTimeSurface = new BitmapImage();
                        imageTimeSurface.BeginInit();
                        imageTimeSurface.UriSource = myUriTimeSurface;
                        imageTimeSurface.EndInit();

                        ko3.imgSource.Height = 20;
                        ko3.imgSource.Source = imageTimeSurface;
                        ko3.OrganizarCabecera();

                        if (esTemporal == 0)
                            at = new AtributoEspNoTemp { Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), tipo.ToString().Replace("Time", "")) };
                        else
                            at = new AtributoEspTemp { Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), tipo.ToString().Replace("Time", "")) };

                        var d = ((MainElementModel)ki.Item).Atributos;
                        if (d.ContainsKey(-1))
                            d[-1] = at;
                        else
                            d.Add(-1, at);

                        var element = ((LSLevelModel)ko3.DesigItem.Item);
                        element.HasTemporalImage = imageSource2.Contains("Time");
                        //element.Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), tipo.ToString().Replace("Time", ""));
                        //ShowProperties(ki);
                    }
                    else
                    {

                        AddMeasure nk3 = new AddMeasure();
                        nk3.Title = "Add Attribute";
                        nk3.tbEtiqueta.Text = "Attribute";
                        nk3.stNivel.Visibility = Visibility.Hidden;
                        nk3.ShowDialog();
                        if (nk3.Estado == "A")
                        {
                            //ko3.lstview.Items.Add(nk3.txtMeasure.Text);
                            List<Utils.MeasureAttribute> CurrentProducts = (List<Utils.MeasureAttribute>)ko3.lstview.ItemsSource;
                            CurrentProducts.Add(new Utils.MeasureAttribute(nk3.EsPrimaryKey, nk3.txtMeasure.Text, esTemporal, tipo));

                            // seteando atributo para mostrar
                            ko3.DesigItem = ki;
                            if (tipo == MeasureAttribute.TypeImageMeasureAttribute.None && esTemporal == 0)
                            {
                                at = new AtributoNoEspNoTemp
                                {
                                    DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                                    Name = nk3.txtMeasure.Text,
                                    Key = (nk3.EsPrimaryKey == 1)
                                ? TypeKey.Y
                                : TypeKey.N
                                };
                            }
                            else
                            {
                                at = new AtributoNoEspTemp
                                {
                                    DataType = new TypeData { TipoDato = TypeDatos.Varchar2 },
                                    Name = nk3.txtMeasure.Text,
                                    Key = (nk3.EsPrimaryKey == 1)
                                ? TypeKey.Y
                                : TypeKey.N
                                };
                            }
                            ((MainElementModel)ki.Item).Atributos.Add(ko3.lstview.Items.Count - 1, at);

                            ko3.lstview.ItemsSource = CurrentProducts;
                            ko3.lstview.Items.Refresh();
                            ko3.lstview.SelectedIndex = ko3.lstview.Items.Count - 1;
                            ko3.OrganizarColumnas();

                        }
                    }
                    break;
                default:
                    break;
            }
        }

        public static string mt_DevolverImagen(string tipo)
        {
            string imageSource = string.Empty;
            switch (tipo)
            {
                case "Line":
                    imageSource = "Resources/Images/Line.png";
                    break;
                case "LineSet":
                    imageSource = "Resources/Images/LineSet.png";
                    break;
                case "Point":
                    imageSource = "Resources/Images/Point.png";
                    break;
                case "PointSet":
                    imageSource = "Resources/Images/PointSet.png";
                    break;
                case "Surface":
                    imageSource = "Resources/Images/Surface.png";
                    break;
                case "SurfaceSet":
                    imageSource = "Resources/Images/SurfaceSet.png";
                    break;
                case "TimeLine":
                    imageSource = "Resources/Images/TimeLine.png";
                    break;
                case "TimeLineSet":
                    imageSource = "Resources/Images/TimeLineSet.png";
                    break;
                case "TimePoint":
                    imageSource = "Resources/Images/TimePoint.png";
                    break;
                case "TimePointSet":
                    imageSource = "Resources/Images/TimePointSet.png";
                    break;
                case "TimeSurface":
                    imageSource = "Resources/Images/TimeSurface.png";
                    break;
                case "TimeSurfaceSet":
                    imageSource = "Resources/Images/TimeSurfaceSet.png";
                    break;
                case "None":
                    imageSource = "Resources/Images/blank.png";
                    break;
                //default:
                //    imageSource = "Resources/Images/blank.png";
                //    break;
            }

            return imageSource;
        }

        public static string mt_DevolverTipo(string imageSource)
        {
            string tipo = string.Empty;

            if (imageSource.Contains("/Line.png"))
            {
                tipo = "Line";
            }
            else if (imageSource.Contains("/LineSet.png"))
            {
                tipo = "LineSet";
            }
            else if (imageSource.Contains("/Point.png"))
            {
                tipo = "Point";
            }
            else if (imageSource.Contains("/PointSet.png"))
            {
                tipo = "PointSet";
            }
            else if (imageSource.Contains("/Surface.png"))
            {
                tipo = "Surface";
            }
            else if (imageSource.Contains("/SurfaceSet.png"))
            {
                tipo = "SurfaceSet";
            }
            else if (imageSource.Contains("/TimeLine.png"))
            {
                tipo = "TimeLine";
            }
            else if (imageSource.Contains("/TimeLineSet.png"))
            {
                tipo = "TimeLineSet";
            }
            else if (imageSource.Contains("/TimePoint.png"))
            {
                tipo = "TimePoint";
            }
            else if (imageSource.Contains("/TimePointSet.png"))
            {
                tipo = "TimePointSet";
            }
            else if (imageSource.Contains("/TimeSurface.png"))
            {
                tipo = "TimeSurface";
            }
            else if (imageSource.Contains("/TimeSurfaceSet.png"))
            {
                tipo = "TimeSurfaceSet";
            }
            else if (imageSource.Contains("/blank.png"))
            {
                tipo = "None";
            }

            return tipo;
        }

        private void Point_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.Point, 0);
        }
        private void Line_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.Line, 0);
        }
        private void Surface_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.Surface, 0);
        }
        private void PointSet_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.PointSet, 0);
        }
        private void LineSet_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.LineSet, 0);
        }
        private void SurfaceSet_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.SurfaceSet, 0);
        }
        private void NonSpatialAtribute_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.None, 0);
        }

        private void TempPoint_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.TimePoint, 1);
        }
        private void TempLine_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.TimeLine, 1);
        }
        private void TempSurface_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.TimeSurface, 1);
        }
        private void TempPointSet_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.TimePointSet, 1);
        }
        private void TempLineSet_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.TimeLineSet, 1);
        }
        private void TempSurfaceSet_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.TimeSurfaceSet, 1);
        }
        private void TempNonSpatialAtribute_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AtributoTemporalNoTemporal(MeasureAttribute.TypeImageMeasureAttribute.None, 1);
        }

        private void OracleDdlScript_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            typeScript = Script.Oracle;
            GenerateScript();
        }

        #region New Command

        private void New_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            #region Prueba
            /*
            if (this.selectionService != null)
                this.selectionService.ClearSelection();

            this.Children.Clear();
            XMLFileName = String.Empty;
            XMLContent = null;
            var win = (Window1)Window.GetWindow(this);
            win.bodyXXX.Title = "File1.xml";
            win.ucProperties.CleanProperties(true);
            win.MyDesigner.Focus();
             * */
            #endregion

            #region Nuevo Documento
            var win = (Window1)Window.GetWindow(this);
            
            // DocumentModel
            DocumentModel dmNew = new DocumentModel();
            int count = win.documentModelsXXX.Items.Count;
            dmNew.Title = "File" + (count + 1).ToString() + ".xml";

            GroupBox gbNew = new GroupBox();

            // ScrollViewer
            ScrollViewer svNew = new ScrollViewer();
            svNew.HorizontalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto;
            svNew.VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto;

            // DesignerCanvas
            DesignerCanvas dcNew = new DesignerCanvas();
            dcNew.Name = "MyDesigner" + (count + 1).ToString();
            dcNew.Focusable = true;
            dcNew.FocusVisualStyle = null;
            dcNew.Background = (Brush)System.Windows.Application.Current.Resources["WindowBackgroundBrush"];
            dcNew.ContextMenu = (ContextMenu)System.Windows.Application.Current.Resources["DesignerCanvasContextMenu"];

            dmNew.Content = gbNew;
            gbNew.Content = svNew;
            svNew.Content = dcNew;

            win.documentModelsXXX.Items.Add(dmNew);
            win.documentModelsXXX.SelectedItem = dmNew;
            dmNew.XMLFileNameXXX = String.Empty;
            dmNew.XMLContentXXX = null;
            dmNew.Focus();
            dmNew.Closing += new EventHandler<CancelEventArgs>(dmNew_Closing);
            #endregion

            #region New
            //if (this.selectionService != null)
            //    this.selectionService.ClearSelection();

            //// Obtengo el contenedor de documentos: DocumentPane y le agrego un documento nuevo
            //ScrollViewer sv = (ScrollViewer)this.Parent;
            //GroupBox gb = (GroupBox)sv.Parent;
            //DocumentModel dm = (DocumentModel)gb.Parent;
            //DocumentPane dp = (DocumentPane)dm.Parent;
            //// Si cerre todos los documentos, creo un nuevo DocumentPane
            //if (dp == null)
            //{
            //    dp = new DocumentPane();
            //}

            //DocumentModel dmNew = new DocumentModel();

            //int count = dp.Items.Count;
            //dmNew.Title = "File" + (count + 1).ToString() + ".xml";

            //GroupBox gbNew = new GroupBox();
            //gbNew.Name = "Body";
            //gbNew.Header = "Design Area";
            //dmNew.Content = gbNew;

            //ScrollViewer svNew = new ScrollViewer();
            //svNew.HorizontalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto;
            //svNew.VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto;
            //gbNew.Content = svNew;

            //DesignerCanvas dcNew = new DesignerCanvas();
            //dcNew.Name = "MyDesigner2";
            //dcNew.Focusable = true;
            //dcNew.FocusVisualStyle = null;
            //dcNew.Background = (Brush)System.Windows.Application.Current.Resources["WindowBackgroundBrush"];
            //dcNew.ContextMenu = (ContextMenu)System.Windows.Application.Current.Resources["DesignerCanvasContextMenu"];
            //svNew.Content = dcNew;
            //dp.Items.Add(dmNew);
            //dmNew.Focus();

            //// Agregando el evento closing y closed
            //dmNew.Closing += new EventHandler<CancelEventArgs>(dmNew_Closing);
            //dmNew.Closed += new EventHandler(dmNew_Closed);
            #endregion
        }

        void dmNew_Closing(object sender, CancelEventArgs e)
        {
            #region Prueba
            string title = String.Empty;
            var win = (Window1)Window.GetWindow(this);

            DocumentModel dmActive;
            dmActive = ((DocumentModel)win.documentModelsXXX.Items[win.documentModelsXXX.SelectedIndex]);

            IEnumerable<DesignerItem> designerItems = ((DesignerCanvas)(((ScrollViewer)((GroupBox)(dmActive).Content).Content).Content)).Children.OfType<DesignerItem>();
            IEnumerable<Connection> connections = ((DesignerCanvas)(((ScrollViewer)((GroupBox)(dmActive).Content).Content).Content)).Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            if (!dmActive.XMLFileNameXXX.Equals(""))
            {
                root.AddFirst(new XElement("FileName", dmActive.XMLFileNameXXX));
                if (dmActive.XMLContentXXX.Value.Equals(root.Value))
                {
                    return;
                }
                else
                {
                    SaveFile(root, route, title);
                }
            }
            else
            {
                string fileName = SaveAsFile(root, title);
                if (!fileName.Equals(String.Empty))
                {
                    dmActive.Title = fileName;
                    dmActive.XMLContentXXX = root;
                    dmActive.XMLFileNameXXX = fileName;
                }
                else
                {
                    return;
                }
            }
            #endregion

            #region Save
            /*
            int index = 0;
            string title = String.Empty;
            DesignerCanvas dcNew = new DesignerCanvas();
            ScrollViewer sv = (ScrollViewer)this.Parent;
            GroupBox gb = (GroupBox)sv.Parent;
            DocumentModel dm = (DocumentModel)gb.Parent;
            DocumentPane dp = (DocumentPane)dm.Parent;
            foreach (DocumentModel dmNew in dp.Items)
            {
                if (dmNew.IsActiveDocument)
                {
                    index = dp.SelectedIndex;
                    GroupBox gbNew = (GroupBox)dmNew.Content;
                    ScrollViewer svNew = (ScrollViewer)gbNew.Content;
                    dcNew = (DesignerCanvas)svNew.Content;
                    title = dmNew.Title;
                    break;
                }
            }

            IEnumerable<DesignerItem> designerItems = dcNew.Children.OfType<DesignerItem>();
            IEnumerable<Connection> connections = dcNew.Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            if (!XMLFileName.Equals(""))
            {
                root.AddFirst(new XElement("FileName", XMLFileName));
                if (XMLContent.Value.Equals(root.Value))
                {
                    return;
                }
                else
                {
                    SaveFile(root, route, title);
                }
            }
            else
            {
                string fileName = SaveAsFile(root, title);
                if (!fileName.Equals(String.Empty))
                {
                    ((DocumentModel)dp.Items[index]).Title = fileName;
                    XMLContent = root;
                    XMLFileName = fileName;
                }
                else
                {
                    return;
                }
            }
            */
            #endregion

            //var win = (Window1)Window.GetWindow(this);
            // Cierro la pestaña activa
            int index = 0;
            //DocumentPane dp = (DocumentPane)win.documentModelsXXX;
            //foreach (DocumentModel dmNew in dp.Items)
            foreach (DocumentModel dmNew in win.documentModelsXXX.Items)
            {
                if (dmNew.IsActiveDocument)
                {
                    dmActive.XMLFileNameXXX = String.Empty;
                    dmActive.XMLContentXXX = null;
                    index = win.documentModelsXXX.SelectedIndex;
                    win.documentModelsXXX.Items.Remove(dmNew);
                    //XMLFileName = String.Empty;
                    //XMLContent = null;
                    return;
                }
            }
        }

        void dmNew_Closed(object sender, EventArgs e)
        {
            System.Diagnostics.Debug.WriteLine(((DocumentContent)sender).Title + " closed");
        }

        #endregion

        #region Exit Command
        private void Exit_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            //ScrollViewer sv = (ScrollViewer)this.Parent;
            //GroupBox gb = (GroupBox)sv.Parent;
            //DocumentModel dm = (DocumentModel)gb.Parent;
            //DocumentPane ad = (DocumentPane)dm.Parent;
            //ResizingPanel rp = (ResizingPanel)ad.Parent;
            //DockingManager dkm = (DockingManager)rp.Parent;
            //Grid grid_1 = (Grid)dkm.Parent;
            //Grid grid_2 = (Grid)grid_1.Parent;
            //Window window = (Window)grid_2.Parent;
            //window.Close();
            #region Prueba
            string title = String.Empty;
            var win = (Window1)Window.GetWindow(this);
            IEnumerable<DesignerItem> designerItems = this.Children.OfType<DesignerItem>();
            IEnumerable<Connection> connections = this.Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            if (!XMLFileName.Equals(""))
            {
                if (root.Element("FileName") == null)
                {
                    root.AddFirst(new XElement("FileName", XMLFileName));
                }
                if (XMLContent.Value.Equals(root.Value))
                {
                    win.Close();
                }
                else
                {
                    //SaveFile(root, route, title);
                    if (MessageBoxResult.Yes == MessageBox.Show("Save changes?", "CSTMTool", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                    {
                        SaveAsFile(root);
                        win.Close();
                    }
                    else
                    {
                        win.Close();
                    }
                }
            }
            else
            {
                string fileName = SaveAsFile(root, title);
                if (!fileName.Equals(String.Empty))
                {
                    win.bodyXXX.Title = fileName;
                    XMLContent = root;
                    XMLFileName = fileName;
                }
                win.Close();
            }
            #endregion
        }
        public bool Exit_Executed(object sender, System.ComponentModel.CancelEventArgs e)
        {
            #region Prueba
            bool result = false;
            string title = String.Empty;
            var win = (Window1)Window.GetWindow(this);
            IEnumerable<DesignerItem> designerItems = this.Children.OfType<DesignerItem>();
            IEnumerable<Connection> connections = this.Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            if (!XMLFileName.Equals(""))
            {
                if (root.Element("FileName") == null)
                {
                    root.AddFirst(new XElement("FileName", XMLFileName));
                }
                if (XMLContent.Value.Equals(root.Value))
                {
                    result = true;
                }
                else
                {
                    if (MessageBoxResult.Yes == MessageBox.Show("Save changes?", "CSTMTool", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                    {
                        SaveFile(root, route, title);
                        result = true;
                    }
                    else
                    {
                        result = true;
                    }
                }
            }
            else
            {
                if (MessageBoxResult.Yes == MessageBox.Show("Save changes?", "CSTMTool", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                {
                    string fileName = SaveAsFile(root, title);
                    if (!fileName.Equals(String.Empty))
                    {
                        win.bodyXXX.Title = fileName;
                        XMLContent = root;
                        XMLFileName = fileName;
                    }
                    result = true;
                }
            }
            return result;
            #endregion
        }
        public bool Exit_Executed(object sender)
        {
            #region Prueba
            bool result = false;
            string title = String.Empty;
            var win = (Window1)Window.GetWindow(this);
            IEnumerable<DesignerItem> designerItems = this.Children.OfType<DesignerItem>();
            IEnumerable<Connection> connections = this.Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            if (!XMLFileName.Equals(""))
            {
                if (root.Element("FileName") == null)
                {
                    root.AddFirst(new XElement("FileName", XMLFileName));
                }
                if (XMLContent.Value.Equals(root.Value))
                {
                    result = true;
                }
                else
                {
                    if (MessageBoxResult.Yes == MessageBox.Show("Save changes?", "CSTMTool", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                    {
                        SaveFile(root, route, title);
                        result = true;
                    }
                    else
                    {
                        result = true;
                    }
                }
            }
            else
            {
                if (MessageBoxResult.Yes == MessageBox.Show("Save changes?", "CSTMTool", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                {
                    string fileName = SaveAsFile(root, title);
                    if (!fileName.Equals(String.Empty))
                    {
                        win.bodyXXX.Title = fileName;
                        XMLContent = root;
                        XMLFileName = fileName;
                    }
                    result = true;
                }
            }
            return result;
            #endregion
        }
        #endregion

        #region Export Image
        private void ExportImage_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            #region Prueba
            var win = (Window1)Window.GetWindow(this);

            IntPtr mainWindowPtr = new WindowInteropHelper(win).Handle;

            System.Drawing.Bitmap memoryImage = null;
            System.Drawing.Image[] images = new System.Drawing.Bitmap[1];
            System.Drawing.Rectangle rc = new System.Drawing.Rectangle();
            int width = 0;
            int height = 0;
            width = Int32.Parse(Math.Round(this.ActualWidth).ToString());
            height = Int32.Parse(Math.Round(this.ActualHeight).ToString());
            rc.Size = new System.Drawing.Size(width, height);
            int positionTopX = Int32.Parse(win.GetValue(LeftProperty).ToString());
            int positionTopY = Int32.Parse(win.GetValue(TopProperty).ToString());

            using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(mainWindowPtr))
            {
                memoryImage = new System.Drawing.Bitmap(rc.Width, rc.Height, graphics);

                using (System.Drawing.Graphics memoryGrahics =
                        System.Drawing.Graphics.FromImage(memoryImage))
                {
                    memoryGrahics.CopyFromScreen(positionTopX + 276, positionTopY + 121, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
                }
            }
            images[0] = memoryImage;

            DocumentModel dmActive;
            dmActive = ((DocumentModel)win.documentModelsXXX.Items[win.documentModelsXXX.SelectedIndex]);

            SaveFileDialog dlg = new SaveFileDialog();
            //dlg.FileName = XMLFileName.Substring(0, XMLFileName.Length - 4);
            dlg.FileName = dmActive.XMLFileNameXXX.Substring(0, dmActive.XMLFileNameXXX.Length - 4);
            dlg.Filter = "JPEG (*.jpg)|*.jpg|GIF (*.gif)|*.gif|Bitmap (*.bmp)|*.bmp|PNG (*.png)|*.png";
            if (dlg.ShowDialog() == true)
            {
                System.Drawing.Imaging.ImageFormat frmt = GetImageFormat(dlg.FileName);

                if (images[0] != null)
                {
                    images[0].Save(dlg.FileName, frmt);
                }
            }
            #endregion

            #region Export Image
            //int index = 0;
            //DesignerCanvas dcNew = new DesignerCanvas();
            //ScrollViewer sv = (ScrollViewer)this.Parent;
            //GroupBox gb = (GroupBox)sv.Parent;
            //DocumentModel dm = (DocumentModel)gb.Parent;
            //DocumentPane dp = (DocumentPane)dm.Parent;
            //foreach (DocumentModel dmNew in dp.Items)
            //{
            //    if (dmNew.IsActiveDocument)
            //    {
            //        index = dp.SelectedIndex;
            //        GroupBox gbNew = (GroupBox)dmNew.Content;
            //        ScrollViewer svNew = (ScrollViewer)gbNew.Content;
            //        dcNew = (DesignerCanvas)svNew.Content;
            //    }
            //}

            //ResizingPanel rp = (ResizingPanel)dp.Parent;
            //DockingManager dkm = (DockingManager)rp.Parent;
            //Grid grid_1 = (Grid)dkm.Parent;
            //Grid grid_2 = (Grid)grid_1.Parent;
            //Window window = (Window)grid_2.Parent;

            //IntPtr mainWindowPtr = new WindowInteropHelper(window).Handle;

            //System.Drawing.Bitmap memoryImage = null;
            //System.Drawing.Image[] images = new System.Drawing.Bitmap[1];
            //System.Drawing.Rectangle rc = new System.Drawing.Rectangle();
            //int width = 0;
            //int height = 0;
            //width = Int32.Parse(Math.Round(dcNew.ActualWidth).ToString());
            //height = Int32.Parse(Math.Round(dcNew.ActualHeight).ToString());
            //rc.Size = new System.Drawing.Size(width, height);
            //int positionTopX = Int32.Parse(window.GetValue(LeftProperty).ToString());
            //int positionTopY = Int32.Parse(window.GetValue(TopProperty).ToString());

            //using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromHwnd(mainWindowPtr))
            //{
            //    memoryImage = new System.Drawing.Bitmap(rc.Width, rc.Height, graphics);

            //    using (System.Drawing.Graphics memoryGrahics =
            //            System.Drawing.Graphics.FromImage(memoryImage))
            //    {
            //        memoryGrahics.CopyFromScreen(positionTopX + 276, positionTopY + 121, 0, 0, rc.Size, System.Drawing.CopyPixelOperation.SourceCopy);
            //    }
            //}
            //images[0] = memoryImage;

            //SaveFileDialog dlg = new SaveFileDialog();
            //dlg.Filter = "JPEG (*.jpg)|*.jpg|GIF (*.gif)|*.gif|Bitmap (*.bmp)|*.bmp|PNG (*.png)|*.png";
            //if (dlg.ShowDialog() == true)
            //{
            //    System.Drawing.Imaging.ImageFormat frmt = GetImageFormat(dlg.FileName);

            //    if (images[0] != null)
            //    {
            //        images[0].Save(dlg.FileName, frmt);
            //    }
            //}
            #endregion
        }

        private System.Drawing.Imaging.ImageFormat GetImageFormat(string fileName)
        {
            System.Drawing.Imaging.ImageFormat f = System.Drawing.Imaging.ImageFormat.Jpeg;
            FileInfo fi = new FileInfo(fileName);
            string ext = fi.Extension.ToUpper();
            switch (ext)
            {
                case ".JPG":
                    f = System.Drawing.Imaging.ImageFormat.Jpeg;
                    break;
                case ".GIF":
                    f = System.Drawing.Imaging.ImageFormat.Gif;
                    break;
                case ".BMP":
                    f = System.Drawing.Imaging.ImageFormat.Bmp;
                    break;
                case ".PNG":
                    f = System.Drawing.Imaging.ImageFormat.Png;
                    break;
            }
            return f;
        }
        #endregion

        #region Close Command
        private void Close_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            #region Prueba
            Exit_Executed(sender);
            New_Executed(sender, e);
            #endregion

            #region Close
            //Save_Executed(sender, e);
            //var win = (Window1)Window.GetWindow(this);
            //// Cierro la pestaña activa
            //int index = 0;
            //DocumentPane dp = (DocumentPane)win.documentModelsXXX;
            //foreach (DocumentModel dmNew in dp.Items)
            //{
            //    if (dmNew.IsActiveDocument)
            //    {
            //        index = dp.SelectedIndex;
            //        dp.Items.Remove(dmNew);
            //        return;
            //    }
            //}
            #endregion
        }

        #endregion

        #region Open Command

        private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            #region Prueba
            /*
            XElement root = LoadSerializedDataFromFile();

            if (root == null)
            {
                return;
            }
            else
            {
                this.Children.Clear();
                //this.selectionService.ClearSelection();
                XMLContent = root;
                XMLFileName = root.Element("FileName").Value;
            }
            var win = (Window1)Window.GetWindow(this);
            this.Focusable = true;
            this.Background = (Brush)System.Windows.Application.Current.Resources["WindowBackgroundBrush"];
            this.ContextMenu = (ContextMenu)System.Windows.Application.Current.Resources["DesignerCanvasContextMenu"];
            this.Margin = new Thickness(10, 10, 0, 0);

            XElement fileNameXML = root.Element("FileName");
            win.bodyXXX.Title = fileNameXML.Value;

            #region Carga de Niveles
            IEnumerable<XElement> itemsXML = root.Elements("DesignerItems").Elements("DesignerItem");
            foreach (XElement itemXML in itemsXML)
            {
                Guid id = new Guid(itemXML.Element("ID").Value);
                DesignerItem item = DeserializeDesignerItem(this, itemXML, id, 0, 0);
                this.Children.Add(item);
                SetConnectorDecoratorTemplate(item);
            }
            #endregion

            #region Carga de Links
            IEnumerable<XElement> connectionsXML = root.Elements("Connections").Elements("Connection");
            foreach (XElement connectionXML in connectionsXML)
            {
                Guid sourceID = new Guid(connectionXML.Element("SourceID").Value);
                Guid sinkID = new Guid(connectionXML.Element("SinkID").Value);

                String sourceConnectorName = connectionXML.Element("SourceConnectorName").Value;
                String sinkConnectorName = connectionXML.Element("SinkConnectorName").Value;
                String itemName = connectionXML.Element("Item").Value;

                Connector sourceConnector = GetConnector(sourceID, sourceConnectorName, this);
                Connector sinkConnector = GetConnector(sinkID, sinkConnectorName, this);

                BaseModel item = Extensions.GetObject<BaseModel>("BusinessModelObject." + itemName);

                LinkModel _LinkClass = (LinkModel)item;
                _LinkClass.StartElement = (MainElementModel)sourceConnector.ParentDesignerItem.Item;
                ((MainElementModel)sourceConnector.ParentDesignerItem.Item).SinkConnections.Add(_LinkClass);

                _LinkClass.EndElement = (MainElementModel)sinkConnector.ParentDesignerItem.Item;
                ((MainElementModel)sinkConnector.ParentDesignerItem.Item).SourceConnections.Add(_LinkClass);

                Connection connection = new Connection(sourceConnector, sinkConnector, item) { LinkClass = _LinkClass };
                //Connection connection = new Connection(sourceConnector, sinkConnector, item) { LinkClass = (LinkModel)Extensions.GetObject<BaseModel>("BusinessModelObject." + itemName) };
                Canvas.SetZIndex(connection, Int32.Parse(connectionXML.Element("zIndex").Value));

                this.Children.Add(connection);
            }
            this.InvalidateVisual();
            //SelectionService.SelectAll();
            //win.bodyXXX.Focus();
            win.MyDesigner.Focus();
            #endregion
            */
            #endregion

            #region Abrir Documento existente
            XElement root = LoadSerializedDataFromFile();

            if (root == null)
            {
                return;
            }

            var win = (Window1)Window.GetWindow(this);

            // DocumentModel
            DocumentModel dmNew = new DocumentModel();

            //XMLContent = root;
            //XMLFileName = root.Element("FileName").Value;
            dmNew.XMLContentXXX = root;
            dmNew.XMLFileNameXXX = root.Element("FileName").Value;

            int count = win.documentModelsXXX.Items.Count;
            dmNew.Title = "File" + (count + 1).ToString() + ".xml";

            GroupBox gbNew = new GroupBox();

            // ScrollViewer
            ScrollViewer svNew = new ScrollViewer();
            svNew.HorizontalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto;
            svNew.VerticalScrollBarVisibility = System.Windows.Controls.ScrollBarVisibility.Auto;

            // DesignerCanvas
            DesignerCanvas dcNew = new DesignerCanvas();
            dcNew.Name = "MyDesigner" + (count + 1).ToString();
            dcNew.Focusable = true;
            dcNew.FocusVisualStyle = null;
            dcNew.Background = (Brush)System.Windows.Application.Current.Resources["WindowBackgroundBrush"];
            dcNew.ContextMenu = (ContextMenu)System.Windows.Application.Current.Resources["DesignerCanvasContextMenu"];

            dmNew.Content = gbNew;
            gbNew.Content = svNew;
            svNew.Content = dcNew;

            win.documentModelsXXX.Items.Add(dmNew);
            win.documentModelsXXX.SelectedItem = dmNew;

            XElement fileNameXML = root.Element("FileName");
            dmNew.Title = fileNameXML.Value;
            this.XMLFileName = fileNameXML.Value;
            this.XMLContent = root;

            dmNew.XMLFileNameXXX = fileNameXML.Value;
            dmNew.XMLContentXXX = root;
            dmNew.Closing += new EventHandler<CancelEventArgs>(dmNew_Closing);

            #region Carga de Niveles
            IEnumerable<XElement> itemsXML = root.Elements("DesignerItems").Elements("DesignerItem");
            foreach (XElement itemXML in itemsXML)
            {
                Guid id = new Guid(itemXML.Element("ID").Value);
                DesignerItem item = DeserializeDesignerItem(dcNew, itemXML, id, 0, 0);
                dcNew.Children.Add(item);
                SetConnectorDecoratorTemplate(item);
            }
            #endregion

            #region Carga de Links
            IEnumerable<XElement> connectionsXML = root.Elements("Connections").Elements("Connection");
            foreach (XElement connectionXML in connectionsXML)
            {
                Guid sourceID = new Guid(connectionXML.Element("SourceID").Value);
                Guid sinkID = new Guid(connectionXML.Element("SinkID").Value);

                String sourceConnectorName = connectionXML.Element("SourceConnectorName").Value;
                String sinkConnectorName = connectionXML.Element("SinkConnectorName").Value;
                String itemName = connectionXML.Element("Item").Value;

                Connector sourceConnector = GetConnector(sourceID, sourceConnectorName, dcNew);
                Connector sinkConnector = GetConnector(sinkID, sinkConnectorName, dcNew);

                BaseModel item = Extensions.GetObject<BaseModel>("BusinessModelObject." + itemName);

                LinkModel _LinkClass = (LinkModel)item;
                _LinkClass.StartElement = (MainElementModel)sourceConnector.ParentDesignerItem.Item;
                ((MainElementModel)sourceConnector.ParentDesignerItem.Item).SinkConnections.Add(_LinkClass);

                _LinkClass.EndElement = (MainElementModel)sinkConnector.ParentDesignerItem.Item;
                ((MainElementModel)sinkConnector.ParentDesignerItem.Item).SourceConnections.Add(_LinkClass);

                Connection connection = new Connection(sourceConnector, sinkConnector, item) { LinkClass = _LinkClass };
                //Connection connection = new Connection(sourceConnector, sinkConnector, item) { LinkClass = (LinkModel)Extensions.GetObject<BaseModel>("BusinessModelObject." + itemName) };
                Canvas.SetZIndex(connection, Int32.Parse(connectionXML.Element("zIndex").Value));

                dcNew.Children.Add(connection);
            }
            #endregion

            dcNew.InvalidateVisual();
            dcNew.Focus();
            #endregion

            #region Open
            //XElement root = LoadSerializedDataFromFile();

            //if (root == null)
            //{
            //    return;
            //}
            //else
            //{
            //    XMLContent = root;
            //    XMLFileName = root.Element("FileName").Value;
            //}

            //DesignerCanvas dcNew = new DesignerCanvas();
            //dcNew.Focusable = true;
            //dcNew.Background = (Brush)System.Windows.Application.Current.Resources["WindowBackgroundBrush"];
            //dcNew.ContextMenu = (ContextMenu)System.Windows.Application.Current.Resources["DesignerCanvasContextMenu"];
            //dcNew.Margin = new Thickness(10, 10, 0, 0);

            //DocumentModel dmNew = new DocumentModel();
            //GroupBox gbNew = new GroupBox();
            //gbNew.Name = "body";
            //gbNew.Header = "Design Area";

            //ScrollViewer svNew = new ScrollViewer();
            //svNew.HorizontalScrollBarVisibility = ScrollBarVisibility.Auto;
            //svNew.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;

            //ScrollViewer sv = (ScrollViewer)this.Parent;
            //GroupBox gb = (GroupBox)sv.Parent;
            //DocumentModel dm = (DocumentModel)gb.Parent;
            //DocumentPane dp = (DocumentPane)dm.Parent;

            //dp.Items.Add(dmNew);

            //XElement fileNameXML = root.Element("FileName");
            //dmNew.Title = fileNameXML.Value;

            //#region Carga de Niveles
            //IEnumerable<XElement> itemsXML = root.Elements("DesignerItems").Elements("DesignerItem");
            //foreach (XElement itemXML in itemsXML)
            //{
            //    Guid id = new Guid(itemXML.Element("ID").Value);
            //    DesignerItem item = DeserializeDesignerItem(dcNew, itemXML, id, 0, 0);
            //    dcNew.Children.Add(item);
            //    SetConnectorDecoratorTemplate(item);
            //}
            //#endregion

            //#region Carga de Links
            //IEnumerable<XElement> connectionsXML = root.Elements("Connections").Elements("Connection");
            //foreach (XElement connectionXML in connectionsXML)
            //{
            //    Guid sourceID = new Guid(connectionXML.Element("SourceID").Value);
            //    Guid sinkID = new Guid(connectionXML.Element("SinkID").Value);

            //    String sourceConnectorName = connectionXML.Element("SourceConnectorName").Value;
            //    String sinkConnectorName = connectionXML.Element("SinkConnectorName").Value;
            //    String itemName = connectionXML.Element("Item").Value;

            //    Connector sourceConnector = GetConnector(sourceID, sourceConnectorName, dcNew);
            //    Connector sinkConnector = GetConnector(sinkID, sinkConnectorName, dcNew);

            //    BaseModel item = Extensions.GetObject<BaseModel>("BusinessModelObject." + itemName);

            //    LinkModel _LinkClass = (LinkModel)item;
            //    _LinkClass.StartElement = (MainElementModel)sourceConnector.ParentDesignerItem.Item;
            //    ((MainElementModel)sourceConnector.ParentDesignerItem.Item).SinkConnections.Add(_LinkClass);

            //    _LinkClass.EndElement = (MainElementModel)sinkConnector.ParentDesignerItem.Item;
            //    ((MainElementModel)sinkConnector.ParentDesignerItem.Item).SourceConnections.Add(_LinkClass);

            //    Connection connection = new Connection(sourceConnector, sinkConnector, item) { LinkClass = _LinkClass };
            //    //Connection connection = new Connection(sourceConnector, sinkConnector, item) { LinkClass = (LinkModel)Extensions.GetObject<BaseModel>("BusinessModelObject." + itemName) };
            //    Canvas.SetZIndex(connection, Int32.Parse(connectionXML.Element("zIndex").Value));

            //    dcNew.Children.Add(connection);
            //}
            //#endregion

            ////dmNew.FirstLoad = false;
            //dmNew.Loaded += new RoutedEventHandler(dmNew_LoadedOpen);

            //// Agregando el evento closing y closed
            //dmNew.Closing += new EventHandler<CancelEventArgs>(dmNew_Closing);
            ////dmNew.Closed += new EventHandler(dmNew_LoadedClosed);

            //svNew.Content = dcNew;
            //gbNew.Content = svNew;
            //dmNew.Content = gbNew;
            //dcNew.InvalidateVisual();
            //dmNew.Focus();
            #endregion
        }

        void dmNew_LoadedOpen(object sender, RoutedEventArgs e)
        {
            //this.Modified = false;
        }

        //void dmNew_LoadedClosing(object sender, RoutedEventArgs e)
        //{
        //    this.Modified = false;
        //}

        //void dmNew_LoadedClosed(object sender, RoutedEventArgs e)
        //{
        //    this.Modified = false;
        //}

        #endregion

        #region Save Command

        private void Save_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            #region Prueba
            string title = String.Empty;
            var win = (Window1)Window.GetWindow(this);

            DocumentModel dmActive;
            dmActive = ((DocumentModel)win.documentModelsXXX.Items[win.documentModelsXXX.SelectedIndex]);

            IEnumerable<DesignerItem> designerItems = ((DesignerCanvas)(((ScrollViewer)((GroupBox)(dmActive).Content).Content).Content)).Children.OfType<DesignerItem>();
            IEnumerable<Connection> connections = ((DesignerCanvas)(((ScrollViewer)((GroupBox)(dmActive).Content).Content).Content)).Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            if (!dmActive.XMLFileNameXXX.Equals(""))
            {
                root.AddFirst(new XElement("FileName", dmActive.XMLFileNameXXX));
                if (dmActive.XMLContentXXX.Value.Equals(root.Value))
                {
                    return;
                }
                else
                {
                    SaveFile(root, route, title);
                }
            }
            else
            {
                string fileName = SaveAsFile(root, title);
                if (!fileName.Equals(String.Empty))
                {
                    dmActive.Title = fileName;
                    dmActive.XMLContentXXX = root;
                    dmActive.XMLFileNameXXX = fileName;
                }
                else
                {
                    return;
                }
            }
            #endregion

            #region Save
            //int index = 0;
            //string title = String.Empty;
            //DesignerCanvas dcNew = new DesignerCanvas();
            //ScrollViewer sv = (ScrollViewer)this.Parent;
            //GroupBox gb = (GroupBox)sv.Parent;
            //gb.Name = "body";
            //DocumentModel dm = (DocumentModel)gb.Parent;
            //DocumentPane dp = (DocumentPane)dm.Parent;
            //dp.Name = "documentModelsXXX";
            //foreach (DocumentModel dmNew in dp.Items)
            //{
            //    if (dmNew.IsActiveDocument)
            //    {
            //        index = dp.SelectedIndex;
            //        GroupBox gbNew = (GroupBox)dmNew.Content;
            //        ScrollViewer svNew = (ScrollViewer)gbNew.Content;
            //        dcNew = (DesignerCanvas)svNew.Content;
            //        title = dmNew.Title;
            //        break;
            //    }
            //}

            //IEnumerable<DesignerItem> designerItems = dcNew.Children.OfType<DesignerItem>();
            //IEnumerable<Connection> connections = dcNew.Children.OfType<Connection>();

            //XElement designerItemsXML = SerializeDesignerItems(designerItems);
            //XElement connectionsXML = SerializeConnections(connections);

            //XElement root = new XElement("Root");
            //root.Add(designerItemsXML);
            //root.Add(connectionsXML);

            //if (!XMLFileName.Equals(""))
            //{
            //    root.AddFirst(new XElement("FileName", XMLFileName));
            //    if (XMLContent.Value.Equals(root.Value))
            //    {
            //        return;
            //    }
            //    else
            //    {
            //        SaveFile(root, route, title);
            //    }
            //}
            //else
            //{
            //    string fileName = SaveAsFile(root, title);
            //    if (!fileName.Equals(String.Empty))
            //    {
            //        ((DocumentModel)dp.Items[index]).Title = fileName;
            //        XMLContent = root;
            //        XMLFileName = fileName;
            //    }
            //    else
            //    {
            //        return;
            //    }
            //}
            #endregion
        }

        #endregion

        #region SaveAs Command

        private void SaveAs_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            #region Prueba
            var win = (Window1)Window.GetWindow(this);

            DocumentModel dmActive;
            dmActive = ((DocumentModel)win.documentModelsXXX.Items[win.documentModelsXXX.SelectedIndex]);

            //IEnumerable<DesignerItem> designerItems = this.Children.OfType<DesignerItem>();
            IEnumerable<DesignerItem> designerItems = ((DesignerCanvas)(((ScrollViewer)((GroupBox)(dmActive).Content).Content).Content)).Children.OfType<DesignerItem>();

            //IEnumerable<Connection> connections = this.Children.OfType<Connection>();
            IEnumerable<Connection> connections = ((DesignerCanvas)(((ScrollViewer)((GroupBox)(dmActive).Content).Content).Content)).Children.OfType<Connection>();

            XElement designerItemsXML = SerializeDesignerItems(designerItems);
            XElement connectionsXML = SerializeConnections(connections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            string file = SaveAsFile(root, dmActive.XMLFileNameXXX);
            if (file.Length > 0)
            {
                //win.bodyXXX.Title = file;
                dmActive.Title = file;
            }
            #endregion

            #region SaveAs
            //int index = 0;
            //DesignerCanvas dcNew = new DesignerCanvas();
            //ScrollViewer sv = (ScrollViewer)this.Parent;
            //GroupBox gb = (GroupBox)sv.Parent;
            //DocumentModel dm = (DocumentModel)gb.Parent;
            //DocumentPane dp = (DocumentPane)dm.Parent;
            //foreach (DocumentModel dmNew in dp.Items)
            //{
            //    if (dmNew.IsActiveDocument)
            //    {
            //        index = dp.SelectedIndex;
            //        GroupBox gbNew = (GroupBox)dmNew.Content;
            //        ScrollViewer svNew = (ScrollViewer)gbNew.Content;
            //        dcNew = (DesignerCanvas)svNew.Content;
            //    }
            //}

            //IEnumerable<DesignerItem> designerItems = dcNew.Children.OfType<DesignerItem>();
            //IEnumerable<Connection> connections = dcNew.Children.OfType<Connection>();

            //XElement designerItemsXML = SerializeDesignerItems(designerItems);
            //XElement connectionsXML = SerializeConnections(connections);

            //XElement root = new XElement("Root");
            //root.Add(designerItemsXML);
            //root.Add(connectionsXML);

            //string file = SaveAsFile(root);
            //((DocumentModel)dp.Items[index]).Title = file;
            #endregion
        }

        #endregion

        #region Print Command

        private void Print_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SelectionService.ClearSelection();

            PrintDialog printDialog = new PrintDialog();

            if (true == printDialog.ShowDialog())
            {
                printDialog.PrintVisual(this, "WPF Diagram");
            }
        }

        #endregion

        #region Copy Command

        private void Copy_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CopyCurrentSelection();
        }

        private void Copy_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = SelectionService.CurrentSelection.Count() > 0;
        }

        #endregion

        #region Paste Command

        private void Paste_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            XElement root = LoadSerializedDataFromClipBoard();

            if (root == null)
                return;

            // create DesignerItems
            Dictionary<Guid, Guid> mappingOldToNewIDs = new Dictionary<Guid, Guid>();
            List<ISelectable> newItems = new List<ISelectable>();
            IEnumerable<XElement> itemsXML = root.Elements("DesignerItems").Elements("DesignerItem");

            double offsetX = Double.Parse(root.Attribute("OffsetX").Value, CultureInfo.InvariantCulture);
            double offsetY = Double.Parse(root.Attribute("OffsetY").Value, CultureInfo.InvariantCulture);

            foreach (XElement itemXML in itemsXML)
            {
                Guid oldID = new Guid(itemXML.Element("ID").Value);
                Guid newID = Guid.NewGuid();
                mappingOldToNewIDs.Add(oldID, newID);
                DesignerItem item = DeserializeDesignerItem(this, itemXML, newID, offsetX, offsetY);
                this.Children.Add(item);
                SetConnectorDecoratorTemplate(item);
                newItems.Add(item);
            }

            // update group hierarchy
            SelectionService.ClearSelection();
            foreach (DesignerItem el in newItems)
            {
                if (el.ParentID != Guid.Empty)
                    el.ParentID = mappingOldToNewIDs[el.ParentID];
            }


            foreach (DesignerItem item in newItems)
            {
                if (item.ParentID == Guid.Empty)
                {
                    SelectionService.AddToSelection(item);
                }
            }

            // create Connections
            IEnumerable<XElement> connectionsXML = root.Elements("Connections").Elements("Connection");
            foreach (XElement connectionXML in connectionsXML)
            {
                Guid oldSourceID = new Guid(connectionXML.Element("SourceID").Value);
                Guid oldSinkID = new Guid(connectionXML.Element("SinkID").Value);

                if (mappingOldToNewIDs.ContainsKey(oldSourceID) && mappingOldToNewIDs.ContainsKey(oldSinkID))
                {
                    Guid newSourceID = mappingOldToNewIDs[oldSourceID];
                    Guid newSinkID = mappingOldToNewIDs[oldSinkID];

                    String sourceConnectorName = connectionXML.Element("SourceConnectorName").Value;
                    String sinkConnectorName = connectionXML.Element("SinkConnectorName").Value;

                    Connector sourceConnector = GetConnector(newSourceID, sourceConnectorName, this);
                    Connector sinkConnector = GetConnector(newSinkID, sinkConnectorName, this);

                    Connection connection = new Connection(sourceConnector, sinkConnector);
                    Canvas.SetZIndex(connection, Int32.Parse(connectionXML.Element("zIndex").Value));
                    this.Children.Add(connection);

                    SelectionService.AddToSelection(connection);
                }
            }

            DesignerCanvas.BringToFront.Execute(null, this);

            // update paste offset
            root.Attribute("OffsetX").Value = (offsetX + 10).ToString();
            root.Attribute("OffsetY").Value = (offsetY + 10).ToString();
            Clipboard.Clear();
            Clipboard.SetData(DataFormats.Xaml, root);
        }

        private void Paste_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = Clipboard.ContainsData(DataFormats.Xaml);
        }

        #endregion

        #region Delete Command

        private void Delete_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DeleteCurrentSelection();
        }

        private void Delete_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.SelectionService.CurrentSelection.Count() > 0;
        }

        #endregion

        #region Cut Command

        private void Cut_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CopyCurrentSelection();
            DeleteCurrentSelection();
        }

        private void Cut_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.SelectionService.CurrentSelection.Count() > 0;
        }

        #endregion

        #region Group Command

        private void Group_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var items = from item in this.SelectionService.CurrentSelection.OfType<DesignerItem>()
                        where item.ParentID == Guid.Empty
                        select item;

            Rect rect = GetBoundingRectangle(items);

            DesignerItem groupItem = new DesignerItem();
            groupItem.Item = Extensions.GetObject<BaseModel>("BusinessModelObject.GroupModel");
            groupItem.IsGroup = true;
            groupItem.Width = rect.Width;
            groupItem.Height = rect.Height;
            Canvas.SetLeft(groupItem, rect.Left);
            Canvas.SetTop(groupItem, rect.Top);
            Canvas groupCanvas = new Canvas();
            groupItem.Content = groupCanvas;
            Canvas.SetZIndex(groupItem, this.Children.Count);
            this.Children.Add(groupItem);

            foreach (DesignerItem item in items)
                item.ParentID = groupItem.ID;

            this.SelectionService.SelectItem(groupItem);
        }

        private void Group_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            int count = (from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                         where item.ParentID == Guid.Empty
                         select item).Count();

            e.CanExecute = count > 1;
        }

        #endregion

        #region Ungroup Command

        private void Ungroup_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var groups = (from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                          where item.IsGroup && item.ParentID == Guid.Empty
                          select item).ToArray();

            foreach (DesignerItem groupRoot in groups)
            {
                var children = from child in SelectionService.CurrentSelection.OfType<DesignerItem>()
                               where child.ParentID == groupRoot.ID
                               select child;

                foreach (DesignerItem child in children)
                    child.ParentID = Guid.Empty;

                this.SelectionService.RemoveFromSelection(groupRoot);
                this.Children.Remove(groupRoot);
                UpdateZIndex();
            }
        }

        private void Ungroup_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            var groupedItem = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                              where item.ParentID != Guid.Empty
                              select item;


            e.CanExecute = groupedItem.Count() > 0;
        }

        #endregion

        #region BringForward Command

        private void BringForward_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            List<UIElement> ordered = (from item in SelectionService.CurrentSelection
                                       orderby Canvas.GetZIndex(item as UIElement) descending
                                       select item as UIElement).ToList();

            int count = this.Children.Count;

            for (int i = 0; i < ordered.Count; i++)
            {
                int currentIndex = Canvas.GetZIndex(ordered[i]);
                int newIndex = Math.Min(count - 1 - i, currentIndex + 1);
                if (currentIndex != newIndex)
                {
                    Canvas.SetZIndex(ordered[i], newIndex);
                    IEnumerable<UIElement> it = this.Children.OfType<UIElement>().Where(item => Canvas.GetZIndex(item) == newIndex);

                    foreach (UIElement elm in it)
                    {
                        if (elm != ordered[i])
                        {
                            Canvas.SetZIndex(elm, currentIndex);
                            break;
                        }
                    }
                }
            }
        }

        private void Order_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            //e.CanExecute = SelectionService.CurrentSelection.Count() > 0;
            e.CanExecute = true;
        }

        #endregion

        #region BringToFront Command

        private void BringToFront_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            List<UIElement> selectionSorted = (from item in SelectionService.CurrentSelection
                                               orderby Canvas.GetZIndex(item as UIElement) ascending
                                               select item as UIElement).ToList();

            List<UIElement> childrenSorted = (from UIElement item in this.Children
                                              orderby Canvas.GetZIndex(item as UIElement) ascending
                                              select item as UIElement).ToList();

            int i = 0;
            int j = 0;
            foreach (UIElement item in childrenSorted)
            {
                if (selectionSorted.Contains(item))
                {
                    int idx = Canvas.GetZIndex(item);
                    Canvas.SetZIndex(item, childrenSorted.Count - selectionSorted.Count + j++);
                }
                else
                {
                    Canvas.SetZIndex(item, i++);
                }
            }
        }

        #endregion

        #region SendBackward Command

        private void SendBackward_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            List<UIElement> ordered = (from item in SelectionService.CurrentSelection
                                       orderby Canvas.GetZIndex(item as UIElement) ascending
                                       select item as UIElement).ToList();

            int count = this.Children.Count;

            for (int i = 0; i < ordered.Count; i++)
            {
                int currentIndex = Canvas.GetZIndex(ordered[i]);
                int newIndex = Math.Max(i, currentIndex - 1);
                if (currentIndex != newIndex)
                {
                    Canvas.SetZIndex(ordered[i], newIndex);
                    IEnumerable<UIElement> it = this.Children.OfType<UIElement>().Where(item => Canvas.GetZIndex(item) == newIndex);

                    foreach (UIElement elm in it)
                    {
                        if (elm != ordered[i])
                        {
                            Canvas.SetZIndex(elm, currentIndex);
                            break;
                        }
                    }
                }
            }
        }

        #endregion

        #region SendToBack Command

        private void SendToBack_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            List<UIElement> selectionSorted = (from item in SelectionService.CurrentSelection
                                               orderby Canvas.GetZIndex(item as UIElement) ascending
                                               select item as UIElement).ToList();

            List<UIElement> childrenSorted = (from UIElement item in this.Children
                                              orderby Canvas.GetZIndex(item as UIElement) ascending
                                              select item as UIElement).ToList();
            int i = 0;
            int j = 0;
            foreach (UIElement item in childrenSorted)
            {
                if (selectionSorted.Contains(item))
                {
                    int idx = Canvas.GetZIndex(item);
                    Canvas.SetZIndex(item, j++);

                }
                else
                {
                    Canvas.SetZIndex(item, selectionSorted.Count + i++);
                }
            }
        }

        #endregion

        #region AlignTop Command

        private void AlignTop_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                select item;

            if (selectedItems.Count() > 1)
            {
                double top = Canvas.GetTop(selectedItems.First());

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = top - Canvas.GetTop(item);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetTop(di, Canvas.GetTop(di) + delta);
                    }
                }
            }
        }

        private void Align_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            //var groupedItem = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
            //                  where item.ParentID == Guid.Empty
            //                  select item;


            //e.CanExecute = groupedItem.Count() > 1;
            e.CanExecute = true;
        }

        #endregion

        #region AlignVerticalCenters Command

        private void AlignVerticalCenters_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                select item;

            if (selectedItems.Count() > 1)
            {
                double bottom = Canvas.GetTop(selectedItems.First()) + selectedItems.First().Height / 2;

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = bottom - (Canvas.GetTop(item) + item.Height / 2);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetTop(di, Canvas.GetTop(di) + delta);
                    }
                }
            }
        }

        #endregion

        #region AlignBottom Command

        private void AlignBottom_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                select item;

            if (selectedItems.Count() > 1)
            {
                double bottom = Canvas.GetTop(selectedItems.First()) + selectedItems.First().Height;

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = bottom - (Canvas.GetTop(item) + item.Height);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetTop(di, Canvas.GetTop(di) + delta);
                    }
                }
            }
        }

        #endregion

        #region AlignLeft Command

        private void AlignLeft_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                select item;

            if (selectedItems.Count() > 1)
            {
                double left = Canvas.GetLeft(selectedItems.First());

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = left - Canvas.GetLeft(item);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetLeft(di, Canvas.GetLeft(di) + delta);
                    }
                }
            }
        }

        #endregion

        #region AlignHorizontalCenters Command

        private void AlignHorizontalCenters_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                select item;

            if (selectedItems.Count() > 1)
            {
                double center = Canvas.GetLeft(selectedItems.First()) + selectedItems.First().Width / 2;

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = center - (Canvas.GetLeft(item) + item.Width / 2);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetLeft(di, Canvas.GetLeft(di) + delta);
                    }
                }
            }
        }

        #endregion

        #region AlignRight Command

        private void AlignRight_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                select item;

            if (selectedItems.Count() > 1)
            {
                double right = Canvas.GetLeft(selectedItems.First()) + selectedItems.First().Width;

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = right - (Canvas.GetLeft(item) + item.Width);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetLeft(di, Canvas.GetLeft(di) + delta);
                    }
                }
            }
        }

        #endregion

        #region DistributeHorizontal Command

        private void DistributeHorizontal_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                let itemLeft = Canvas.GetLeft(item)
                                orderby itemLeft
                                select item;

            if (selectedItems.Count() > 1)
            {
                double left = Double.MaxValue;
                double right = Double.MinValue;
                double sumWidth = 0;
                foreach (DesignerItem item in selectedItems)
                {
                    left = Math.Min(left, Canvas.GetLeft(item));
                    right = Math.Max(right, Canvas.GetLeft(item) + item.Width);
                    sumWidth += item.Width;
                }

                double distance = Math.Max(0, (right - left - sumWidth) / (selectedItems.Count() - 1));
                double offset = Canvas.GetLeft(selectedItems.First());

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = offset - Canvas.GetLeft(item);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetLeft(di, Canvas.GetLeft(di) + delta);
                    }
                    offset = offset + item.Width + distance;
                }
            }
        }

        private void Distribute_Enabled(object sender, CanExecuteRoutedEventArgs e)
        {
            //var groupedItem = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
            //                  where item.ParentID == Guid.Empty
            //                  select item;


            //e.CanExecute = groupedItem.Count() > 1;
            e.CanExecute = true;
        }

        #endregion

        #region DistributeVertical Command

        private void DistributeVertical_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            var selectedItems = from item in SelectionService.CurrentSelection.OfType<DesignerItem>()
                                where item.ParentID == Guid.Empty
                                let itemTop = Canvas.GetTop(item)
                                orderby itemTop
                                select item;

            if (selectedItems.Count() > 1)
            {
                double top = Double.MaxValue;
                double bottom = Double.MinValue;
                double sumHeight = 0;
                foreach (DesignerItem item in selectedItems)
                {
                    top = Math.Min(top, Canvas.GetTop(item));
                    bottom = Math.Max(bottom, Canvas.GetTop(item) + item.Height);
                    sumHeight += item.Height;
                }

                double distance = Math.Max(0, (bottom - top - sumHeight) / (selectedItems.Count() - 1));
                double offset = Canvas.GetTop(selectedItems.First());

                foreach (DesignerItem item in selectedItems)
                {
                    double delta = offset - Canvas.GetTop(item);
                    foreach (DesignerItem di in SelectionService.GetGroupMembers(item))
                    {
                        Canvas.SetTop(di, Canvas.GetTop(di) + delta);
                    }
                    offset = offset + item.Height + distance;
                }
            }
        }

        #endregion

        #region SelectAll Command

        private void SelectAll_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SelectionService.SelectAll();
        }

        #endregion

        #region Helper Methods

        private XElement LoadSerializedDataFromFile()
        {
            OpenFileDialog openFile = new OpenFileDialog();
            openFile.Filter = "Designer Files (*.xml)|*.xml|All Files (*.*)|*.*";

            if (openFile.ShowDialog() == true)
            {
                try
                {
                    route = openFile.FileName;
                    return XElement.Load(openFile.FileName);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.StackTrace, e.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return null;
        }

        public void SaveFile(XElement xElement, string route)
        {
            try
            {
                xElement.Save(route);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        public void SaveFile(XElement xElement, string route, string title)
        {
            try
            {
                if (xElement.Element("FileName") == null)
                {
                    xElement.AddFirst(new XElement("FileName", title));
                }
                xElement.Save(route);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        public string SaveAsFile(XElement xElement)
        {
            string fileName = String.Empty;
            SaveFileDialog saveFile = new SaveFileDialog();
            if (XMLFileName.Length > 0)
            {
                saveFile.FileName = XMLFileName;
            }
            else
            {
                saveFile.FileName = "File1.xml";
            }
            saveFile.Filter = "Files (*.xml)|*.xml|All Files (*.*)|*.*";
            if (saveFile.ShowDialog() == true)
            {
                try
                {
                    xElement.AddFirst(new XElement("FileName", saveFile.SafeFileName));
                    xElement.Save(saveFile.FileName);
                    route = saveFile.FileName;
                    fileName = saveFile.SafeFileName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            return fileName;
        }

        public string SaveAsFile(XElement xElement, string title)
        {
            string fileName = String.Empty;
            SaveFileDialog saveFile = new SaveFileDialog();
            if (title.Equals(""))
            {
                saveFile.FileName = "File1.xml";
            }
            else
            {
                saveFile.FileName = title;
            }
            saveFile.Filter = "Files (*.xml)|*.xml|All Files (*.*)|*.*";
            if (saveFile.ShowDialog() == true)
            {
                try
                {
                    xElement.AddFirst(new XElement("FileName", saveFile.SafeFileName));
                    xElement.Save(saveFile.FileName);
                    route = saveFile.FileName;
                    fileName = saveFile.SafeFileName;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.StackTrace, ex.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            return fileName;
        }

        private XElement LoadSerializedDataFromClipBoard()
        {
            if (Clipboard.ContainsData(DataFormats.Xaml))
            {
                String clipboardData = Clipboard.GetData(DataFormats.Xaml) as String;

                if (String.IsNullOrEmpty(clipboardData))
                    return null;
                try
                {
                    return XElement.Load(new StringReader(clipboardData));
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.StackTrace, e.Message, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return null;
        }

        public XElement SerializeDesignerItems(IEnumerable<DesignerItem> designerItems)
        {
            XElement serializedItems = new XElement("DesignerItems");

            string criterio = String.Empty;
            string attributeXml = string.Empty;
            string contentXaml = string.Empty;
            string nombreNivel = string.Empty;
            string imageResource = string.Empty;
            string spatialPredicate = string.Empty;
            bool addModel = true;

            foreach (DesignerItem item in designerItems)
            {
                XElement serializedAttributes = new XElement("Attributes");
                addModel = true;
                switch (item.Tipo)
                {
                    case "FactRelationShipModel":
                        GUIFactTable ko1 = new GUIFactTable();
                        List<Utils.MeasureAttribute> CurrentFact = (List<Utils.MeasureAttribute>)((GUIFactTable)item.Content).lstview.ItemsSource;
                        ko1.lstview.ItemsSource = CurrentFact;
                        contentXaml = XamlWriter.Save(ko1);

                        nombreNivel = ((GUIFactTable)item.Content).lblName.Content.ToString();
                        break;
                    case "LevelModel":
                        GUILevel ko2 = new GUILevel();
                        List<Utils.MeasureAttribute> CurrentLevel = (List<Utils.MeasureAttribute>)((GUILevel)item.Content).lstview.ItemsSource;
                        ko2.lstview.ItemsSource = CurrentLevel;
                        contentXaml = XamlWriter.Save(ko2);
                        imageResource = ((GUILevel)item.Content).imgSource.Source.ToString();
                        nombreNivel = ((GUILevel)item.Content).lblName.Content.ToString();
                        break;
                    case "LSLevelModel":
                        GUILSLevel ko3 = new GUILSLevel();
                        List<Utils.MeasureAttribute> CurrentLSLevel = (List<Utils.MeasureAttribute>)((GUILSLevel)item.Content).lstview.ItemsSource;
                        ko3.lstview.ItemsSource = CurrentLSLevel;
                        contentXaml = XamlWriter.Save(ko3);
                        imageResource = ((GUILSLevel)item.Content).imgSource.Source.ToString();
                        nombreNivel = ((GUILSLevel)item.Content).lblName.Content.ToString();
                        break;
                    case "CriterionModel":
                        GUICriterion ko4 = new GUICriterion();
                        //List<Utils.MeasureAttribute> CurrentCriterion = (List<Utils.MeasureAttribute>)((GUICriterion)item.Content).lstview.ItemsSource;
                        //ko4.lstview.ItemsSource = CurrentCriterion;
                        contentXaml = XamlWriter.Save(ko4);
                        //imageResource = ((GUICriterion)item.Content).imgSource.Source.ToString();
                        nombreNivel = ((GUICriterion)item.Content).lblName.Content.ToString();
                        break;
                    default:
                        addModel = false;
                        break;
                }

                if (addModel)
                {
                    MainElementModel onk = (MainElementModel)item.Item;
                    Dictionary<int, BaseField> _atributos = onk.Atributos;

                    if (item.Tipo == "FactRelationShipModel")
                        spatialPredicate = ((FactRelationShipModel)onk).SpatialPredicate.ToString();

                    int intInicio = 0;
                    int intFinal = _atributos.Count;

                    if (_atributos.ContainsKey(-1))
                    {
                        intInicio = -1;
                        intFinal = _atributos.Count - 1;
                    }

                    for (int k = intInicio; k < intFinal; k++)
                    {
                        BaseField om = _atributos[k];
                        attributeXml = XamlWriter.Save(om);

                        XElement serializedAtribute = new XElement("Attribute",
                                                      new XElement("Content", attributeXml)
                                                  );

                        serializedAttributes.Add(serializedAtribute);
                    }

                    XElement serializedItem = new XElement("DesignerItem",
                                                      new XElement("Left", Canvas.GetLeft(item)),
                                                      new XElement("Top", Canvas.GetTop(item)),
                                                      new XElement("Width", item.Width),
                                                      new XElement("Height", item.Height),
                                                      new XElement("ID", item.ID),
                                                      new XElement("zIndex", Canvas.GetZIndex(item)),
                                                      new XElement("NameRelation", item.NameItemRelation),//item.IsGroup),
                                                      new XElement("IsGroup", false),//item.IsGroup),
                                                      new XElement("ParentID", Guid.Empty), //item.ParentID),
                                                      new XElement("SpatialPredicate", spatialPredicate),
                                                      new XElement("Name", nombreNivel),
                                                      new XElement("Image", imageResource),
                                                      new XElement("Content", contentXaml),
                                                      new XElement("Criterio", criterio),
                                                      new XElement("ListAttribute", serializedAttributes)
                                                  );

                    serializedItems.Add(serializedItem);
                }

            }


            /*
            XElement serializedItems = new XElement("DesignerItems",
                                       from item in designerItems
                                       let contentXaml = XamlWriter.Save(((DesignerItem)item).Content)
                                       select new XElement("DesignerItem",
                                                  new XElement("Left", Canvas.GetLeft(item)),
                                                  new XElement("Top", Canvas.GetTop(item)),
                                                  new XElement("Width", item.Width),
                                                  new XElement("Height", item.Height),
                                                  new XElement("ID", item.ID),
                                                  new XElement("zIndex", Canvas.GetZIndex(item)),
                                                  new XElement("IsGroup", item.IsGroup),
                                                  new XElement("ParentID", item.ParentID),
                                                  new XElement("Content", contentXaml)
                                              )
                                   );
            */
            return serializedItems;
        }

        public XElement SerializeConnections(IEnumerable<Connection> connections)
        {
            var serializedConnections = new XElement("Connections",
                           from connection in connections
                           select new XElement("Connection",
                                      new XElement("SourceID", connection.Source.ParentDesignerItem.ID),
                                      new XElement("SinkID", connection.Sink.ParentDesignerItem.ID),
                                      new XElement("Item", connection.Item.GetType().Name),
                               //new XElement("NameItemSource", connection.NameItemSource),
                               //new XElement("NameItemDestination", connection.NameItemDestination),
                                      new XElement("SourceConnectorName", connection.Source.Name),
                                      new XElement("SinkConnectorName", connection.Sink.Name),
                               //new XElement("StarElement", connection.LinkClass.StartElement),
                               //new XElement("EndElement", connection.LinkClass.EndElement),
                                      new XElement("SourceArrowSymbol", connection.SourceArrowSymbol),
                                      new XElement("SinkArrowSymbol", connection.SinkArrowSymbol),
                                      new XElement("zIndex", Canvas.GetZIndex(connection))
                                     )
                                  );

            return serializedConnections;
        }

        public DesignerItem DeserializeDesignerItem(DesignerCanvas dc, XElement itemXML, Guid id, double OffsetX, double OffsetY)
        {
            DesignerItem item = new DesignerItem(id);
            item.Width = Double.Parse(itemXML.Element("Width").Value, CultureInfo.InvariantCulture);
            item.Height = Double.Parse(itemXML.Element("Height").Value, CultureInfo.InvariantCulture);
            item.ParentID = new Guid(itemXML.Element("ParentID").Value);
            item.IsGroup = Boolean.Parse(itemXML.Element("IsGroup").Value);
            item.NameItemRelation = itemXML.Element("NameRelation").Value.ToString();
            Canvas.SetLeft(item, Double.Parse(itemXML.Element("Left").Value, CultureInfo.InvariantCulture) + OffsetX);
            Canvas.SetTop(item, Double.Parse(itemXML.Element("Top").Value, CultureInfo.InvariantCulture) + OffsetY);
            Canvas.SetZIndex(item, Int32.Parse(itemXML.Element("zIndex").Value));
            //Object content = XamlReader.Load(XmlReader.Create(new StringReader(itemXML.Element("Content").Value)));
            //item.Content = content;           
            string nombreNivel = itemXML.Element("Name").Value.ToString();
            string imageSource = itemXML.Element("Image").Value.ToString();
            string atributos = string.Empty;//itemXML.Element("ListAttribute").Value.ToString();
            string spatialPredicate = itemXML.Element("SpatialPredicate").Value.ToString();


            string xaml = itemXML.Element("Content").Value;
            xaml = xaml.Replace("lstview", "lstview2");
            xaml = xaml.Replace("lblName", "lblName2");
            xaml = xaml.Replace("mask", "mask2");
            xaml = xaml.Replace("maskFactTable", "mask2FactTable");
            xaml = xaml.Replace("grView", "grView2");
            xaml = xaml.Replace("grvFactTable", "grvFactTable2");
            xaml = xaml.Replace("gvCabecera", "gvCabecera2");
            xaml = xaml.Replace("lblLevel", "lblLevel2");
            xaml = xaml.Replace("imgSource", "imgSource2");
            xaml = xaml.Replace("borderHeader", "borderHeader2");
            xaml = xaml.Replace("<av:VisualBrush.Visual><av:Border CornerRadius=\"9,9,9,9\" Background=\"#FFFFFFFF\" Name=\"mask2\"", "<av:VisualBrush.Visual><av:Border CornerRadius=\"9,9,9,9\" Background=\"#FFFFFFFF\" Name=\"mask3\"");
            xaml = xaml.Replace("<av:VisualBrush.Visual><av:Border CornerRadius=\"7,7,7,7\" Background=\"#FFFFFFFF\" Name=\"mask2FactTable\"", "<av:VisualBrush.Visual><av:Border CornerRadius=\"7,7,7,7\" Background=\"#FFFFFFFF\" Name=\"mask3FactTable\"");


            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xaml);
            XmlNodeReader reader = new XmlNodeReader(xmlDoc);
            Object ContentPrueba = XamlReader.Load(reader);

            GUILevel contentLevel = ContentPrueba as GUILevel;
            GUILSLevel contentLSLevel = ContentPrueba as GUILSLevel;
            GUIFactTable contentFactTable = ContentPrueba as GUIFactTable;
            GUICriterion contentCriterion = ContentPrueba as GUICriterion;

            /////         

            if (contentFactTable != null)
            {
                #region Objeto GUIFactTable
                GUIFactTable content2 = contentFactTable;//(GUIFactTable)XamlReader.Load(reader);

                ListView tb = content2.FindName("lstview2") as ListView;
                List<Utils.MeasureAttribute> CurrentItems = new List<Utils.MeasureAttribute>();
                foreach (Utils.MeasureAttribute ji in tb.Items)
                {
                    CurrentItems.Add(ji);
                }

                GUIFactTable content = new GUIFactTable();
                content.lstview.ItemsSource = CurrentItems;
                content.DesigItem = item;
                content.lblName.Content = nombreNivel;

                item.Content = content;
                item.Tipo = "FactRelationShipModel";
                contextMenuSpatial(ref item);

                //item.Item = GetBaseModelFromXamlReader(content);
                item.Item = Extensions.GetObject<BaseModel>("BusinessModelObject.FactRelationShipModel");
                //((MainElementModel)item.Item).Name = nombreNivel;

                MainElementModel onk = (MainElementModel)item.Item;
                onk.Name = nombreNivel;
                switch (spatialPredicate)
                {
                    case "Touches":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Touches;
                        break;
                    case "Within":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Within;
                        break;
                    case "Crosses":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Crosses;
                        break;
                    case "Overlaps":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Overlaps;
                        break;
                    case "Disjoint":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Disjoint;
                        break;
                    case "Contains":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Contains;
                        break;
                    case "Equals":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Equals;
                        break;
                    case "Intersects":
                        ((FactRelationShipModel)onk).SpatialPredicate = TypeSpatialPredicate.Intersects;
                        break;
                }
                #endregion
            }
            else
            {
                if (contentLevel != null)
                {
                    #region Objeto GUILevel
                    GUILevel content2 = contentLevel;//(GUILevel)XamlReader.Load(reader);

                    ListView tb = content2.FindName("lstview2") as ListView;
                    List<Utils.MeasureAttribute> CurrentItems = new List<Utils.MeasureAttribute>();
                    foreach (Utils.MeasureAttribute ji in tb.Items)
                    {
                        CurrentItems.Add(ji);
                    }

                    GUILevel content = new GUILevel();
                    content.lstview.ItemsSource = CurrentItems;
                    content.DesigItem = item;
                    content.lblName.Content = nombreNivel;

                    Uri myUriTimeSurface = new Uri(imageSource, UriKind.RelativeOrAbsolute);
                    BitmapImage imageTimeSurface = new BitmapImage();
                    imageTimeSurface.BeginInit();
                    imageTimeSurface.UriSource = myUriTimeSurface;
                    imageTimeSurface.EndInit();

                    content.imgSource.Height = 20;
                    content.imgSource.Source = imageTimeSurface;

                    item.Content = content;
                    item.Tipo = "LevelModel";

                    contextMenuTemporal(ref item);

                    //item.Item = GetBaseModelFromXamlReader(content);
                    item.Item = Extensions.GetObject<BaseModel>("BusinessModelObject.LevelModel");
                    ((MainElementModel)item.Item).Name = nombreNivel;

                    var element = ((LevelModel)content.DesigItem.Item);
                    element.HasTemporalImage = imageSource.Contains("Time");
                    //element.Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), mt_DevolverTipo(imageSource).ToString().Replace("Time", ""));
                    #endregion
                }
                else
                {
                    if (contentLSLevel != null)
                    {
                        #region Objeto GUILSLevel
                        GUILSLevel content2 = contentLSLevel;//(GUILSLevel)XamlReader.Load(reader);

                        ListView tb = content2.FindName("lstview2") as ListView;
                        List<Utils.MeasureAttribute> CurrentItems = new List<Utils.MeasureAttribute>();
                        foreach (Utils.MeasureAttribute ji in tb.Items)
                        {
                            CurrentItems.Add(ji);
                        }

                        GUILSLevel content = new GUILSLevel();
                        content.lstview.ItemsSource = CurrentItems;
                        content.DesigItem = item;
                        content.lblName.Content = nombreNivel;

                        Uri myUriTimeSurface = new Uri(imageSource, UriKind.RelativeOrAbsolute);
                        BitmapImage imageTimeSurface = new BitmapImage();
                        imageTimeSurface.BeginInit();
                        imageTimeSurface.UriSource = myUriTimeSurface;
                        imageTimeSurface.EndInit();

                        content.imgSource.Height = 20;
                        content.imgSource.Source = imageTimeSurface;

                        item.Content = content;
                        item.Tipo = "LSLevelModel";
                        contextMenuTemporal(ref item);

                        //item.Item = GetBaseModelFromXamlReader(content);
                        item.Item = Extensions.GetObject<BaseModel>("BusinessModelObject.LSLevelModel");
                        ((MainElementModel)item.Item).Name = nombreNivel;

                        var element = ((LSLevelModel)content.DesigItem.Item);
                        element.HasTemporalImage = imageSource.Contains("Time");
                        //element.Geometry = (TypeGeometry)Enum.Parse(typeof(TypeGeometry), mt_DevolverTipo(imageSource).ToString().Replace("Time", ""));
                        #endregion
                    }
                    else
                    {
                        if (contentCriterion != null)
                        {
                            #region Objeto Criterion
                            GUICriterion content2 = contentCriterion;
                            GUICriterion content = new GUICriterion();
                            content.DesigItem = item;
                            content.lblName.Content = nombreNivel;
                            item.Content = content;
                            item.Tipo = "CriterionModel";

                            contextMenuTemporal(ref item);

                            item.Item = Extensions.GetObject<BaseModel>("BusinessModelObject.CriterionModel");
                            ((MainElementModel)item.Item).Name = nombreNivel;

                            item.Criterio = content.Criterio;
                            DesignerItem newItemDestination;
                            newItemDestination = new DesignerItem();
                            newItemDestination = GetDesignerItem(dc, item.NameItemRelation.ToString());

                            if (newItemDestination!=null && newItemDestination.Item is MainElementModel && item.Item is CriterionModel)
                            {
                                ((CriterionModel)item.Item).DestinationItem =
                                    (MainElementModel)(newItemDestination.Item);
                                ((MainElementModel)(newItemDestination.Item)).Criterion = (CriterionModel)item.Item;
                            }

                            dc.SelectionService.SelectItem(newItemDestination);
                            dc.SelectionService.AddToSelection(item);

                            dc.Group_Executed(null, null);

                            #endregion
                        }
                        else
                        {

                            Object content = XamlReader.Load(XmlReader.Create(new StringReader(itemXML.Element("Content").Value)));
                            item.Content = content;
                            //TODO: Analizar si es necesario implementar la propiedad ITEM
                            contextMenuCriterion(ref item);
                        }
                    }
                }
            }

            int cont = 1;
            IEnumerable<XElement> itemsXML = itemXML.Elements("ListAttribute").Elements("Attributes").Elements("Attribute");
            foreach (XElement itemXML2 in itemsXML)
            {
                atributos = itemXML2.Element("Content").Value.ToString();

                XmlDocument xmlDoc2 = new XmlDocument();
                xmlDoc2.LoadXml(atributos);
                XmlNodeReader reader2 = new XmlNodeReader(xmlDoc2);
                Object ContentAtributo = XamlReader.Load(reader2);

                BaseField onk2 = (BaseField)ContentAtributo;
                if (onk2.Name == null)
                {
                    ((MainElementModel)item.Item).Atributos.Add(-1, onk2);
                }
                else
                {
                    ((MainElementModel)item.Item).Atributos.Add(cont - 1, onk2);
                    cont = cont + 1;
                }
            }

            var guiElement = item.Content as GUIElement;
            if (guiElement != null) guiElement.DesigItem = item;

            return item;
        }

        private void CopyCurrentSelection()
        {
            IEnumerable<DesignerItem> selectedDesignerItems = this.SelectionService.CurrentSelection.OfType<DesignerItem>();

            List<Connection> selectedConnections = this.SelectionService.CurrentSelection.OfType<Connection>().ToList();

            foreach (Connection connection in this.Children.OfType<Connection>())
            {
                if (!selectedConnections.Contains(connection))
                {
                    DesignerItem sourceItem = (from item in selectedDesignerItems
                                               where item.ID == connection.Source.ParentDesignerItem.ID
                                               select item).FirstOrDefault();

                    DesignerItem sinkItem = (from item in selectedDesignerItems
                                             where item.ID == connection.Sink.ParentDesignerItem.ID
                                             select item).FirstOrDefault();

                    if (sourceItem != null &&
                        sinkItem != null &&
                        BelongToSameGroup(sourceItem, sinkItem))
                    {
                        selectedConnections.Add(connection);
                    }
                }
            }

            XElement designerItemsXML = SerializeDesignerItems(selectedDesignerItems);
            XElement connectionsXML = SerializeConnections(selectedConnections);

            XElement root = new XElement("Root");
            root.Add(designerItemsXML);
            root.Add(connectionsXML);

            root.Add(new XAttribute("OffsetX", 10));
            root.Add(new XAttribute("OffsetY", 10));

            Clipboard.Clear();
            Clipboard.SetData(DataFormats.Xaml, root);
        }

        private void DeleteCurrentSelection()
        {
            foreach (Connection connection in SelectionService.CurrentSelection.OfType<Connection>())
            {
                connection.LinkClass.StartElement.SourceConnections.Remove(connection.LinkClass);
                connection.LinkClass.EndElement.SinkConnections.Remove(connection.LinkClass);
                this.Children.Remove(connection);
            }

            foreach (DesignerItem item in SelectionService.CurrentSelection.OfType<DesignerItem>())
            {
                Control cd = item.Template.FindName("PART_ConnectorDecorator", item) as Control;

                List<Connector> connectors = new List<Connector>();
                GetConnectors(cd, connectors);

                foreach (Connector connector in connectors)
                {
                    foreach (Connection con in connector.Connections)
                    {
                        this.Children.Remove(con);
                    }
                }
                this.Children.Remove(item);
            }

            SelectionService.ClearSelection();
            UpdateZIndex();
        }

        private void UpdateZIndex()
        {
            List<UIElement> ordered = (from UIElement item in this.Children
                                       orderby Canvas.GetZIndex(item as UIElement)
                                       select item as UIElement).ToList();

            for (int i = 0; i < ordered.Count; i++)
            {
                Canvas.SetZIndex(ordered[i], i);
            }
        }

        private static Rect GetBoundingRectangle(IEnumerable<DesignerItem> items)
        {
            double x1 = Double.MaxValue;
            double y1 = Double.MaxValue;
            double x2 = Double.MinValue;
            double y2 = Double.MinValue;

            foreach (DesignerItem item in items)
            {
                x1 = Math.Min(Canvas.GetLeft(item), x1);
                y1 = Math.Min(Canvas.GetTop(item), y1);

                x2 = Math.Max(Canvas.GetLeft(item) + item.Width, x2);
                y2 = Math.Max(Canvas.GetTop(item) + item.Height, y2);
            }

            return new Rect(new Point(x1, y1), new Point(x2, y2));
        }

        private void GetConnectors(DependencyObject parent, List<Connector> connectors)
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
            for (int i = 0; i < childrenCount; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(parent, i);
                if (child is Connector)
                {
                    connectors.Add(child as Connector);
                }
                else
                    GetConnectors(child, connectors);
            }
        }

        public Connector GetConnector(Guid itemID, String connectorName, DesignerCanvas dCanvas)
        {
            DesignerItem designerItem = (from item in dCanvas.Children.OfType<DesignerItem>()
                                         where item.ID == itemID
                                         select item).FirstOrDefault();

            Control connectorDecorator = designerItem.Template.FindName("PART_ConnectorDecorator", designerItem) as Control;
            connectorDecorator.ApplyTemplate();

            return connectorDecorator.Template.FindName(connectorName, connectorDecorator) as Connector;
        }

        private bool BelongToSameGroup(IGroupable item1, IGroupable item2)
        {
            IGroupable root1 = SelectionService.GetGroupRoot(item1);
            IGroupable root2 = SelectionService.GetGroupRoot(item2);

            return (root1.ID == root2.ID);
        }

        private string SetFormatName(string name)
        {
            return name.Replace(" ", "_");
        }

        #endregion

        #region Generation of scripts
        void GenerateScript()
        {
            try
            {
                var saveFile = new SaveFileDialog
                                   {
                                       FileName = "script.sql",
                                       Filter = "Files (*.sql)|*.sql|All Files (*.*)|*.*"
                                   };
                if (saveFile.ShowDialog() != true) return;
                using (var sw = new StreamWriter(saveFile.SafeFileName))
                {
                    var sb = new StringBuilder();
                    var ie = Children.OfType<Connection>();
                    var ge = ie.GetEnumerator();
                    while (ge.MoveNext())
                    {
                        if (!ge.Current.LinkClass.IsWrote)
                            WriteScript(ge.Current.LinkClass, sb);
                    }
                    if(ie.Count()==0)
                    {
                        var gei = Children.OfType<DesignerItem>().GetEnumerator();
                        while (gei.MoveNext())
                        {
                            if (!gei.Current.Item.IsWrote)
                                WriteScript((MainElementModel)gei.Current.Item, sb);
                        }
                    }
                    sw.Write(sb.ToString());
                }

                // set iswrote = true for all objects
                var gecnn = Children.OfType<Connection>().Where(m => m.LinkClass.IsWrote).GetEnumerator();
                while (gecnn.MoveNext())
                {
                    gecnn.Current.LinkClass.IsWrote = false;
                }

                var gedi = Children.OfType<DesignerItem>().Where(m => m.Item.IsWrote).GetEnumerator();
                while (gedi.MoveNext())
                {
                    gedi.Current.Item.IsWrote = false;
                }
                MessageBox.Show("File created succesfully","CSTMTool",MessageBoxButton.OK,MessageBoxImage.Information);
            }
            catch (Exception)
            {
                MessageBox.Show("File created unsuccesfully", "CSTMTool",MessageBoxButton.OK,MessageBoxImage.Error);
            }
        }
        void WriteScript(MainElementModel model, StringBuilder write)
        {

            switch (typeScript)
            {
                case Script.Oracle:
                    OracleScript(model, write);
                    model.IsWrote = true;
                    break;
            }

        }
        void WriteScript(LinkModel connection, StringBuilder write)
        {

            switch (typeScript)
            {
                case Script.Oracle:
                    OracleScript(connection.StartElement, write);
                    connection.IsWrote = true;
                    OracleScript(connection.EndElement, write);
                    connection.IsWrote = true;
                    break;
            }

        }
        string PutValues(TypeData typeData)
        {
            if (typeData.Precision == 0) return string.Empty;

            var value = typeData.Precision.ToString();
            if (typeData.TipoDato == TypeDatos.Number)
                value += (typeData.Escala == 0) ? "" : "," + typeData.Escala;

            if(!string.IsNullOrEmpty(value))
                value = "(" + value + ")";

            return value;
        }

        void OracleScript(MainElementModel element, StringBuilder script)
        {
            var ge1 = element.SourceConnections.Where(m => m.IsWrote == false).GetEnumerator();
            while (ge1.MoveNext())
                WriteScript(ge1.Current, script);

            if(element.Criterion!=null && !element.Criterion.IsWrote)
            {
                element.Criterion.IsWrote = true;
                var ge = element.Criterion.SourceConnections.Where(m => m.IsWrote == false).GetEnumerator();
                while (ge.MoveNext())
                    WriteScript(ge.Current, script); 
            }

            if (element is CriterionModel)
                OracleScript(((CriterionModel)element).DestinationItem, script);
            else
            {

                var keyAttributes = new List<BaseField>();
                var tempAttributes = new List<BaseField>();
                if (!element.IsWrote)
                {
                    #region Create types
                    if (script.Length == 0)
                    {
                        script.AppendLine("create type InstantType as object (Instant date);");
                        script.AppendLine("create type InstantSetType as table of InstantType;");
                        script.AppendLine("create type IntervalType as object (FromTime date, ToTime date);");
                        script.AppendLine("create type IntervalSetType as table of IntervalType;");
                        script.AppendLine();
                    }
                    #endregion
                    if (element is LevelModel || element is LSLevelModel)
                    {
                        #region Temporal attributes
                        foreach (KeyValuePair<int, BaseField> kvp in element.Atributos)
                        {
                            if (kvp.Key == -1) continue;
                            var aet = kvp.Value.Parse<AtributoEspTemp>(typeof(AtributoEspTemp));
                            var anet = kvp.Value.Parse<AtributoNoEspTemp>(typeof(AtributoNoEspTemp));

                            if (aet == null && anet == null) continue;

                            var name = SetFormatName((aet != null) ? aet.Name : anet.Name);
                            var type = anet != null ? anet.DataType.TipoDato.ToString() : "varchar2";
                            var set1 = string.Empty;
                            var temporalSupport1 = string.Empty;

                            if (aet != null)
                            {
                                set1 = (aet.TemporalSupport == TypeAtributoTemporalSupport.Interval
                                    || aet.TemporalSupport == TypeAtributoTemporalSupport.Instant)
                                          ? string.Empty
                                          : "Set";
                                switch (aet.TemporalSupport)
                                {
                                    case TypeAtributoTemporalSupport.Interval: temporalSupport1 = "Interval"; break;
                                    case TypeAtributoTemporalSupport.SetOfIntervals: temporalSupport1 = "Interval"; break;
                                    case TypeAtributoTemporalSupport.Instant: temporalSupport1 = "Instant"; break;
                                    case TypeAtributoTemporalSupport.SetOfInstants: temporalSupport1 = "Instant"; break;
                                }
                            }
                            if (anet != null)
                            {
                                set1 = (anet.TemporalSupport == TypeAtributoTemporalSupport.Interval
                                    || anet.TemporalSupport == TypeAtributoTemporalSupport.Instant)
                                          ? string.Empty
                                          : "Set";
                                switch (anet.TemporalSupport)
                                {
                                    case TypeAtributoTemporalSupport.Interval: temporalSupport1 = "Interval"; break;
                                    case TypeAtributoTemporalSupport.SetOfIntervals: temporalSupport1 = "Interval"; break;
                                    case TypeAtributoTemporalSupport.Instant: temporalSupport1 = "Instant"; break;
                                    case TypeAtributoTemporalSupport.SetOfInstants: temporalSupport1 = "Instant"; break;
                                }
                            }

                            script.AppendFormat(@"create type {0}Type as object (
Value {1}{2},
VT{0} {4}{3}Type);

create type {0}TabType as table of {0}Type;", name, type
                                            , anet != null ? PutValues(anet.DataType) : "(25)"
                                            , set1
                                            , temporalSupport1);
                            script.AppendLine();
                        }
                        #endregion
                        #region Create type table

                        PropertyInfo pi = null;
                        if (element.Atributos.ContainsKey(-1)) pi = element.Atributos[-1].GetType().GetProperty("Geometry");
                        var geometry = pi == null ? TypeGeometry.None : (TypeGeometry)pi.GetValue(element.Atributos[-1], null);
                        pi = element.GetType().GetProperty("HasTemporalImage");
                        var isTemporal = pi == null ? false : (bool)pi.GetValue(element, null);

                        var set = string.Empty;
                        var temporalSupport = string.Empty;


                        if (element.Atributos.ContainsKey(-1) && geometry != TypeGeometry.None && isTemporal)
                        {
                            var aet = element.Atributos[-1] as AtributoEspTemp;
                            var anet = element.Atributos[-1] as AtributoNoEspTemp;

                            if ((aet != null) || anet != null)
                            {

                                if (aet != null)
                                {
                                    set = (aet.TemporalSupport == TypeAtributoTemporalSupport.Interval
                                        || aet.TemporalSupport == TypeAtributoTemporalSupport.Instant)
                                              ? string.Empty
                                              : "Set";
                                    switch (aet.TemporalSupport)
                                    {
                                        case TypeAtributoTemporalSupport.Interval:temporalSupport = "Interval";break;
                                        case TypeAtributoTemporalSupport.SetOfIntervals:temporalSupport = "Interval";break;
                                        case TypeAtributoTemporalSupport.Instant:temporalSupport = "Instant";break;
                                        case TypeAtributoTemporalSupport.SetOfInstants:temporalSupport = "Instant";break;
                                    }
                                }
                                if (anet != null)
                                {
                                    set = (anet.TemporalSupport == TypeAtributoTemporalSupport.Interval
                                        || anet.TemporalSupport == TypeAtributoTemporalSupport.Instant)
                                              ? string.Empty
                                              : "Set";

                                    switch (anet.TemporalSupport)
                                    {
                                        case TypeAtributoTemporalSupport.Interval:temporalSupport = "Interval";break;
                                        case TypeAtributoTemporalSupport.SetOfIntervals:temporalSupport = "Interval";break;
                                        case TypeAtributoTemporalSupport.Instant:temporalSupport = "Instant";break;
                                        case TypeAtributoTemporalSupport.SetOfInstants:temporalSupport = "Instant";break;
                                    }
                                }
                                script.AppendLine(string.Format(
                                    @"create type GeometryType as object (
Value mdsys.sdo_geometry,
VTGeometry {1}{0}Type);
create type GeometryTabType as table of GeometryType;", set
                                                      ,temporalSupport));
                            }
                        }

                        Action<MainElementModel> writeTypeName = delegate(MainElementModel model)
                                                                     {
                                                                         var ienn =
                                                                             model.SourceConnections.Where(
                                                                                 m => m is NNModel || m is NNLCModel);

                                                                         var criterion = model as CriterionModel;
                                                                         var name = (criterion != null)
                                                                                        ? criterion.DestinationItem.Name
                                                                                        : model.Name;
                                                                         if (ienn.Count() > 0)
                                                                         {
                                                                             var genn = ienn.GetEnumerator();
                                                                             while (genn.MoveNext())
                                                                             {
                                                                                 script.AppendLine(string.Format("create type {0}{1}Type as ({0}Ref  REF {0}Type);  ", SetFormatName(genn.Current.StartElement.Name), SetFormatName(name)));
                                                                                 script.AppendLine(string.Format("create type {0}{1}TabType as table of {0}{1}Type;  ", SetFormatName(genn.Current.StartElement.Name), SetFormatName(name)));
                                                                             }
                                                                         }
                                                                         else
                                                                         {
                                                                             script.AppendLine(string.Format("create type {0}Type as object (  ", SetFormatName(name))); // type name
                                                                         }
                                                                     };
                        if (element.Criterion != null)
                            writeTypeName(element.Criterion);
                        else
                            writeTypeName(element);

                        if (geometry != TypeGeometry.None && isTemporal)
                        {
                            script.AppendLine("Geometry GeometryTabType,");
                        } // geometry
                        else if (geometry != TypeGeometry.None && !isTemporal)
                        {
                            script.AppendLine("Geometry mdsys.sdo geometry,");
                        }
                        if (element is LSLevelModel)
                        {
                            script.AppendLine(string.Format("LS{0} Interval{1}Type,"
                                                            , SetFormatName(element.Name)
                                                            ,
                                                            ((LSLevelModel) element).TemporalSupport ==
                                                            TypeNivelTemporalSupport.Interval
                                                                ? ""
                                                                : "Set"));
                        } // LS}


                        for (var i = 0; i < element.Atributos.Count; i++)
                        {
                            #region atributos
                            if (!element.Atributos.ContainsKey(i)) continue;

                            var anent = element.Atributos[i] as AtributoNoEspNoTemp;

                            if (anent != null)
                            {
                                var ieanent = element.SourceConnections.Where(m => m is NNModel || m is NNLCModel);
                                if (ieanent.Count() == 0)
                                {
                                    script.AppendLine(string.Format("{0} {1}{2},"
                                                                , SetFormatName(anent.Name)
                                                                , anent.DataType.TipoDato
                                                                , PutValues(anent.DataType)));
                                }
                                if (anent.Key == TypeKey.Y) keyAttributes.Add(element.Atributos[i]);
                            }

                            var aet = element.Atributos[i] as AtributoEspTemp;
                            var anet = element.Atributos[i] as AtributoNoEspTemp;
                            if (aet != null || anet != null)
                            {
                                script.AppendLine(string.Format("{0} {0}TabType,", SetFormatName((aet != null) ? aet.Name : anet.Name)));

                                if (anet != null && anet.Key == TypeKey.Y) keyAttributes.Add(element.Atributos[i]);

                                tempAttributes.Add(aet != null ? (BaseField)aet : anet);
                            }

                            #endregion
                        }
                        Action<MainElementModel> writeReferencesTypes = delegate(MainElementModel model)
                        {
                            for (var j = 0; j < model.SourceConnections.Count; j++)
                            {
                                if (model.SourceConnections[j] is UnoNModel)
                                {
                                    script.AppendLine(
                                        string.Format(
                                            "{0}Ref REF {0}Type,",
                                            SetFormatName(
                                                model.
                                                    SourceConnections
                                                    [j].
                                                    StartElement
                                                    .Name)));
                                }
                            }
                        };
                        if (element.Criterion != null)
                            writeReferencesTypes(element.Criterion);
                        else
                            writeReferencesTypes(element);

                        script[script.Length - 3] = ')';
                        script[script.Length - 2] = ';';
                        script[script.Length - 1] = ' ';
                        script.AppendLine();
                        script.AppendLine();
                        #endregion
                        #region Create table
                        script.AppendLine(string.Format("create table {0} of {0}Type( ", SetFormatName(element.Name)));
                        // constrains 
                        if (keyAttributes.Count > 0 || element.SourceConnections.Count > 0)
                        {
                            // primary keys
                            var keys = new StringBuilder();
                            keyAttributes.ForEach(f => keys.Append(f.Name + ","));
                            if (keys.Length > 0)
                            {
                                script.AppendLine(string.Format("constraint {0}PK primary key ({1}),"
                                                            , SetFormatName(element.Name)
                                                            , SetFormatName(keys.ToString().Remove(keys.Length - 1, 1))));
                            }

                        }
                        // references
                        Action<MainElementModel> writeConstrains = delegate(MainElementModel model)
                                                                {
                                                                    var criterion = model as CriterionModel;
                                                                    var name = (criterion != null)
                                                                                   ? criterion.DestinationItem.Name
                                                                                   : model.Name;
                                                                    for (var i = 0; i < model.SourceConnections.Count; i++)
                                                                    {
                                                                        if (model.SourceConnections[i] is UnoNModel)
                                                                        {
                                                                            script.AppendLine(string.Format("{0}Ref NOT NULL,",
                                                                               SetFormatName(model.SourceConnections[i].StartElement.Name)));
                                                                            script.AppendLine(string.Format("constraint {1}FK{2} foreign key ({0}Ref) references {0},"
                                                                                , SetFormatName(model.SourceConnections[i].StartElement.Name)
                                                                                , SetFormatName(name)
                                                                                , i + 1));

                                                                        }

                                                                        if (model.SourceConnections[i] is NNModel || model.SourceConnections[i] is NNLCModel)
                                                                        {
                                                                            script.AppendLine(string.Format("In{0} {0}{1}TabType,", SetFormatName(model.SourceConnections[i].StartElement.Name), SetFormatName(name)));
                                                                        }
                                                                    }
                                                                };
                        if (element.Criterion != null)
                            writeConstrains(element.Criterion);
                        else
                            writeConstrains(element);


                        // nestead table
                        if ((element is LSLevelModel || element is LevelModel))
                        {
                            if(geometry!=TypeGeometry.None && isTemporal)
                            {
                                if (((element.SourceConnections.Where(m => m is UnoNVTModel).Count() > 0 ||
                                element.SinkConnections.Where(m => m is UnoNVTModel).Count() > 0)) && set != string.Empty)
                                    script.AppendLine("nested table Geometry store as GeometryNT (nested table VTGeometry store as VTGeometryNT),");
                                else
                                    script.AppendLine("nested table Geometry store as GeometryNT,");
                            }
                            
                            var isSet = false;
                            tempAttributes.ForEach(delegate(BaseField k)
                                                       {
                                                           var b = k as AtributoEspTemp;
                                                           var c = k as AtributoNoEspTemp;

                                                           if (b != null)
                                                               isSet = (b.TemporalSupport ==
                                                                        TypeAtributoTemporalSupport.SetOfInstants
                                                                        ||
                                                                        b.TemporalSupport ==
                                                                        TypeAtributoTemporalSupport.SetOfIntervals);
                                                           if (c != null)
                                                               isSet = (c.TemporalSupport ==
                                                                        TypeAtributoTemporalSupport.SetOfInstants
                                                                        ||
                                                                        c.TemporalSupport ==
                                                                        TypeAtributoTemporalSupport.SetOfIntervals);

                                                           if (isSet)
                                                               script.AppendLine(string.Format(
                                                                   "nested table {0} store as {0}NT (nested tableVT{0} store as VT{0}NT),"
                                                                   , SetFormatName(k.Name)));
                                                           else
                                                               script.AppendLine(string.Format("nested table {0} store as {0}NT,", SetFormatName(k.Name)));
                                                       });

                            if ((element is LSLevelModel) && ((LSLevelModel)element).TemporalSupport != TypeNivelTemporalSupport.Interval)
                                script.AppendLine(string.Format("nested table LS{0} store as LS{0}NT,", SetFormatName(element.Name)));

                            var genn2 = element.SourceConnections.Where(m => m is NNModel || m is NNLCModel).GetEnumerator();
                            while (genn2.MoveNext())
                            {
                                script.AppendLine(string.Format("nested table In{0} store as In{0}NT,", SetFormatName(genn2.Current.StartElement.Name)));
                            }
                        }

                        script[script.Length - 3] = ')';
                        script[script.Length - 2] = ';';
                        script[script.Length - 1] = ' ';
                        script.AppendLine();
                        #endregion
                    }
                    #region Create unonvt
                    Action<MainElementModel> writeUnoNVT =
                        delegate(MainElementModel model)
                        {
                            var criterion = model as CriterionModel;
                            var name = (criterion != null) ? criterion.DestinationItem.Name : model.Name;
                            var ge = model.SourceConnections.Where(m => m is UnoNVTModel).GetEnumerator();
                            while (ge.MoveNext())
                            {
                                #region Create type table and table

                                var ls = ge.Current.StartElement as LSLevelModel;
                                var ts = string.Empty;
                                if (ls != null)
                                    ts = (ls.TemporalSupport == TypeNivelTemporalSupport.Interval) ? "" : "Set";

                                script.AppendLine(string.Format(@"create type {0}{1}Type as object (
{0}Ref  REF {0}Type, 
LS{0}{1} Interval{2}Type);

create table {0}{1} (
{1}Ref REF {1}Type references {1},
In{0} {0}{1}Type)
nested table In{0}.LS{0}{1} store as LS{0}{1}NT; "
                                    , SetFormatName(ge.Current.StartElement.Name)
                                    , SetFormatName(name)
                                    , ts));
                                #endregion
                            }

                        };
                    if (element.Criterion != null)
                        writeUnoNVT(element.Criterion);
                    else
                        writeUnoNVT(element);
                    #endregion
                    #region Create nnvt
                    Action<MainElementModel> writeNnVt = delegate(MainElementModel model)
                     {
                         var criterion = model as CriterionModel;
                         var name = (criterion != null) ? criterion.DestinationItem.Name : model.Name;
                         var ge = model.SourceConnections.Where(m => m is NNVTModel).GetEnumerator();
                         while (ge.MoveNext())
                         {

                             var ls = ge.Current.StartElement as LSLevelModel;
                             var ts = string.Empty;
                             if (ls != null)
                                 ts = (ls.TemporalSupport == TypeNivelTemporalSupport.Interval) ? "" : "Set";

                             script.AppendLine(
                                string.Format(
                                    @"create type {0}{1}Type as (
{0}Ref  REF {0}Type,
LS{0}{1} Interval{2}Type);

create type {0}{1}TabType as table of {0}{1}Type;
create table {0}{1} (
{1}Ref REF {1}Type references {1},
In{0} {0}{1}TabType);
nested table In{0} store as In{0}NT (nested table LS{0}{1} store as LS{0}{1}NT);"
                                    , SetFormatName(ge.Current.StartElement.Name)
                                    , SetFormatName(name)
                                    , ts));
                         }
                     };
                    if (element.Criterion != null)
                        writeNnVt(element.Criterion);
                    else
                        writeNnVt(element);
                    #endregion
                    #region Create factrelationship
                    if (element is FactRelationShipModel)
                    {
                        script.AppendLine(string.Format("create table {0}(", SetFormatName(element.Name)));
                        for (var i = 0; i < element.SourceConnections.Count; i++)
                        {
                            script.AppendLine(string.Format("{0}Ref REF {0}Type,"
                                , SetFormatName(element.SourceConnections[i].StartElement.Name)));
                            script.AppendLine(
                                   string.Format("constraint {2}FK{1} foreign key ({0}Ref) references {0},"
                                                 , SetFormatName(element.SourceConnections[i].StartElement.Name)
                                                 , i + 1
                                                 , SetFormatName(element.Name)));
                        }
                        for (var i = 0; i < element.Atributos.Count; i++)
                        {
                            var mne = element.Atributos[i] as MedidaNoEspacial;
                            if (mne != null) script.AppendLine(string.Format("{0} {1}{2},"
                                                                , SetFormatName(mne.Name)
                                                                , mne.DataType.TipoDato
                                                                , PutValues(mne.DataType)));

                            var me = element.Atributos[i] as MedidaEspacial;
                            if (me != null) script.AppendLine(string.Format("{0} mdsys.sdo_geometry,",SetFormatName(me.Name)));
                        }
                        script[script.Length - 3] = ')';
                        script[script.Length - 2] = ';';
                        script[script.Length - 1] = ' ';
                        script.AppendLine();
                    }
                    #endregion
                    element.IsWrote = true;
                }
            }
        }
        #endregion

        static BaseModel GetBaseModelFromXamlReader(object content)
        {
            var grid = content as Grid;
            if (grid == null) return default(BaseModel);

            var image = grid.Children[0] as Image;
            return image == null ? default(BaseModel) : Extensions.GetObject<BaseModel>("BusinessModelObject." + image.Tag);
        }

        public void ShowProperties(DesignerItem designerItem)
        {
            var win = (Window1)Window.GetWindow(this);
            if (win == null || designerItem == null) return;

            if (designerItem.Item == null) return;
            var item = Convert.ChangeType(designerItem.Item, designerItem.Item.GetType());
            if (item != null) win.ucProperties.ShowProperties(designerItem);
        }


    }
}

